ast-graph-builder.cc revision b8a8cc1952d61a2f3a2568848933943a543b5d3e
1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/ast-graph-builder.h"
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler.h"
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/control-builders.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/machine-operator.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/node-properties.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/node-properties-inl.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/full-codegen.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/parser.h"
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/scopes.h"
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler {
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstGraphBuilder::AstGraphBuilder(CompilationInfo* info, JSGraph* jsgraph)
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : StructuredGraphBuilder(jsgraph->graph(), jsgraph->common()),
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      info_(info),
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      jsgraph_(jsgraph),
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      globals_(0, info->zone()),
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      breakable_(NULL),
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      execution_context_(NULL) {
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  InitializeAstVisitor(info->zone());
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::GetFunctionClosure() {
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!function_closure_.is_set()) {
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Parameter -1 is special for the function closure
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const Operator* op = common()->Parameter(-1);
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* node = NewNode(op, graph()->start());
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    function_closure_.set(node);
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return function_closure_.get();
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::GetFunctionContext() {
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!function_context_.is_set()) {
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Parameter (arity + 1) is special for the outer context of the function
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const Operator* op = common()->Parameter(info()->num_parameters() + 1);
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* node = NewNode(op, graph()->start());
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    function_context_.set(node);
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return function_context_.get();
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool AstGraphBuilder::CreateGraph() {
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Scope* scope = info()->scope();
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(graph() != NULL);
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set up the basic structure of the graph.
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int parameter_count = info()->num_parameters();
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  graph()->SetStart(graph()->NewNode(common()->Start(parameter_count)));
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize the top-level environment.
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Environment env(this, scope, graph()->start());
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_environment(&env);
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Build node to initialize local function context.
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* closure = GetFunctionClosure();
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* outer = GetFunctionContext();
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* inner = BuildLocalFunctionContext(outer, closure);
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Push top-level function scope for the function body.
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ContextScope top_context(this, scope, inner);
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Build the arguments object if it is used.
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BuildArgumentsObject(scope->arguments());
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Emit tracing call if requested to do so.
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_trace) {
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NewNode(javascript()->Runtime(Runtime::kTraceEnter, 0));
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Visit implicit declaration of the function name.
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (scope->is_function_scope() && scope->function() != NULL) {
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitVariableDeclaration(scope->function());
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Visit declarations within the function scope.
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitDeclarations(scope->declarations());
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(mstarzinger): This should do an inlined stack check.
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* node = NewNode(javascript()->Runtime(Runtime::kStackGuard, 0));
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrepareFrameState(node, BailoutId::FunctionEntry());
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Visit statements in the function body.
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitStatements(info()->function()->body());
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (HasStackOverflow()) return false;
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Emit tracing call if requested to do so.
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_trace) {
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(mstarzinger): Only traces implicit return.
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* return_value = jsgraph()->UndefinedConstant();
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NewNode(javascript()->Runtime(Runtime::kTraceExit, 1), return_value);
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Return 'undefined' in case we can fall off the end.
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* control = NewNode(common()->Return(), jsgraph()->UndefinedConstant());
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UpdateControlDependencyToLeaveFunction(control);
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Finish the basic structure of the graph.
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->UpdateControlDependency(exit_control());
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  graph()->SetEnd(NewNode(common()->End()));
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Left-hand side can only be a property, a global or a variable slot.
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Determine the left-hand side kind of an assignment.
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic LhsKind DetermineLhsKind(Expression* expr) {
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Property* property = expr->AsProperty();
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(expr->IsValidReferenceExpression());
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LhsKind lhs_kind =
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (property == NULL) ? VARIABLE : (property->key()->IsPropertyName())
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          ? NAMED_PROPERTY
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          : KEYED_PROPERTY;
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return lhs_kind;
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Helper to find an existing shared function info in the baseline code for the
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// given function literal. Used to canonicalize SharedFunctionInfo objects.
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic Handle<SharedFunctionInfo> SearchSharedFunctionInfo(
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Code* unoptimized_code, FunctionLiteral* expr) {
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int start_position = expr->start_position();
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (RelocIterator it(unoptimized_code); !it.done(); it.next()) {
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RelocInfo* rinfo = it.rinfo();
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue;
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* obj = rinfo->target_object();
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (obj->IsSharedFunctionInfo()) {
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (shared->start_position() == start_position) {
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return Handle<SharedFunctionInfo>(shared);
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Handle<SharedFunctionInfo>();
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochStructuredGraphBuilder::Environment* AstGraphBuilder::CopyEnvironment(
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StructuredGraphBuilder::Environment* env) {
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new (zone()) Environment(*reinterpret_cast<Environment*>(env));
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstGraphBuilder::Environment::Environment(AstGraphBuilder* builder,
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          Scope* scope,
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          Node* control_dependency)
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : StructuredGraphBuilder::Environment(builder, control_dependency),
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      parameters_count_(scope->num_parameters() + 1),
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      locals_count_(scope->num_stack_slots()),
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      parameters_node_(NULL),
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      locals_node_(NULL),
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      stack_node_(NULL) {
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(scope->num_parameters() + 1, parameters_count());
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Bind the receiver variable.
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* receiver = builder->graph()->NewNode(common()->Parameter(0),
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             builder->graph()->start());
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  values()->push_back(receiver);
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Bind all parameter variables. The parameter indices are shifted by 1
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // (receiver is parameter index -1 but environment index 0).
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < scope->num_parameters(); ++i) {
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* parameter = builder->graph()->NewNode(common()->Parameter(i + 1),
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                builder->graph()->start());
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values()->push_back(parameter);
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Bind all local variables to undefined.
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  values()->insert(values()->end(), locals_count(), undefined_constant);
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstGraphBuilder::Environment::Environment(const Environment& copy)
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : StructuredGraphBuilder::Environment(
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          static_cast<StructuredGraphBuilder::Environment>(copy)),
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      parameters_count_(copy.parameters_count_),
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      locals_count_(copy.locals_count_),
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      parameters_node_(copy.parameters_node_),
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      locals_node_(copy.locals_node_),
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      stack_node_(copy.stack_node_) {}
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::Environment::UpdateStateValues(Node** state_values,
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                     int offset, int count) {
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool should_update = false;
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node** env_values = (count == 0) ? NULL : &values()->at(offset);
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (*state_values == NULL || (*state_values)->InputCount() != count) {
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    should_update = true;
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(static_cast<size_t>(offset + count) <= values()->size());
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < count; i++) {
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if ((*state_values)->InputAt(i) != env_values[i]) {
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        should_update = true;
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (should_update) {
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const Operator* op = common()->StateValues(count);
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    (*state_values) = graph()->NewNode(op, count, env_values);
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::Environment::Checkpoint(
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BailoutId ast_id, OutputFrameStateCombine combine) {
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UpdateStateValues(&parameters_node_, 0, parameters_count());
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UpdateStateValues(&locals_node_, parameters_count(), locals_count());
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UpdateStateValues(&stack_node_, parameters_count() + locals_count(),
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    stack_height());
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* op = common()->FrameState(JS_FRAME, ast_id, combine);
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return graph()->NewNode(op, parameters_node_, locals_node_, stack_node_,
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          GetContext(),
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          builder()->jsgraph()->UndefinedConstant());
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own,
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        Expression::Context kind)
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : kind_(kind), owner_(own), outer_(own->ast_context()) {
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  owner()->set_ast_context(this);  // Push.
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  original_height_ = environment()->stack_height();
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstGraphBuilder::AstContext::~AstContext() {
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  owner()->set_ast_context(outer_);  // Pop.
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstGraphBuilder::AstEffectContext::~AstEffectContext() {
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(environment()->stack_height() == original_height_);
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstGraphBuilder::AstValueContext::~AstValueContext() {
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(environment()->stack_height() == original_height_ + 1);
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstGraphBuilder::AstTestContext::~AstTestContext() {
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(environment()->stack_height() == original_height_ + 1);
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::AstEffectContext::ProduceValue(Node* value) {
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The value is ignored.
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::AstValueContext::ProduceValue(Node* value) {
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Push(value);
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::AstTestContext::ProduceValue(Node* value) {
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Push(owner()->BuildToBoolean(value));
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::AstEffectContext::ConsumeValue() { return NULL; }
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::AstValueContext::ConsumeValue() {
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return environment()->Pop();
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::AstTestContext::ConsumeValue() {
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return environment()->Pop();
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstGraphBuilder::BreakableScope* AstGraphBuilder::BreakableScope::FindBreakable(
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BreakableStatement* target) {
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BreakableScope* current = this;
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (current != NULL && current->target_ != target) {
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    owner_->environment()->Drop(current->drop_extra_);
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current = current->next_;
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(current != NULL);  // Always found (unless stack is malformed).
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return current;
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::BreakableScope::BreakTarget(BreakableStatement* stmt) {
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FindBreakable(stmt)->control_->Break();
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::BreakableScope::ContinueTarget(BreakableStatement* stmt) {
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FindBreakable(stmt)->control_->Continue();
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitForValueOrNull(Expression* expr) {
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (expr == NULL) {
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return environment()->Push(jsgraph()->NullConstant());
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValue(expr);
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) {
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < exprs->length(); ++i) {
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitForValue(exprs->at(i));
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitForValue(Expression* expr) {
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AstValueContext for_value(this);
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasStackOverflow()) {
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    expr->Accept(this);
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitForEffect(Expression* expr) {
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AstEffectContext for_effect(this);
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasStackOverflow()) {
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    expr->Accept(this);
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitForTest(Expression* expr) {
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AstTestContext for_condition(this);
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!HasStackOverflow()) {
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    expr->Accept(this);
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) {
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Variable* variable = decl->proxy()->var();
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VariableMode mode = decl->mode();
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET;
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (variable->location()) {
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::UNALLOCATED: {
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Handle<Oddball> value = variable->binding_needs_init()
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  ? isolate()->factory()->the_hole_value()
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  : isolate()->factory()->undefined_value();
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      globals()->Add(variable->name(), zone());
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      globals()->Add(value, zone());
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::PARAMETER:
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::LOCAL:
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (hole_init) {
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* value = jsgraph()->TheHoleConstant();
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        environment()->Bind(variable, value);
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::CONTEXT:
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (hole_init) {
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* value = jsgraph()->TheHoleConstant();
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        const Operator* op = javascript()->StoreContext(0, variable->index());
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        NewNode(op, current_context(), value);
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::LOOKUP:
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNIMPLEMENTED();
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) {
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Variable* variable = decl->proxy()->var();
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (variable->location()) {
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::UNALLOCATED: {
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Handle<SharedFunctionInfo> function =
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Compiler::BuildFunctionInfo(decl->fun(), info()->script(), info());
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Check for stack-overflow exception.
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (function.is_null()) return SetStackOverflow();
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      globals()->Add(variable->name(), zone());
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      globals()->Add(function, zone());
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::PARAMETER:
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::LOCAL: {
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForValue(decl->fun());
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* value = environment()->Pop();
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      environment()->Bind(variable, value);
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::CONTEXT: {
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForValue(decl->fun());
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* value = environment()->Pop();
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      const Operator* op = javascript()->StoreContext(0, variable->index());
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      NewNode(op, current_context(), value);
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::LOOKUP:
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNIMPLEMENTED();
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* decl) {
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitImportDeclaration(ImportDeclaration* decl) {
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitExportDeclaration(ExportDeclaration* decl) {
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitModuleLiteral(ModuleLiteral* modl) { UNREACHABLE(); }
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitModuleVariable(ModuleVariable* modl) {
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitModulePath(ModulePath* modl) { UNREACHABLE(); }
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitModuleUrl(ModuleUrl* modl) { UNREACHABLE(); }
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitBlock(Block* stmt) {
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockBuilder block(this);
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BreakableScope scope(this, stmt, &block, 0);
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (stmt->labels() != NULL) block.BeginBlock();
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (stmt->scope() == NULL) {
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Visit statements in the same scope, no declarations.
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitStatements(stmt->statements());
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const Operator* op = javascript()->CreateBlockContext();
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* scope_info = jsgraph()->Constant(stmt->scope()->GetScopeInfo());
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* context = NewNode(op, scope_info, GetFunctionClosure());
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ContextScope scope(this, stmt->scope(), context);
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Visit declarations and statements in a block scope.
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitDeclarations(stmt->scope()->declarations());
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitStatements(stmt->statements());
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (stmt->labels() != NULL) block.EndBlock();
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitModuleStatement(ModuleStatement* stmt) {
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) {
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForEffect(stmt->expression());
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) {
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Do nothing.
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitIfStatement(IfStatement* stmt) {
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IfBuilder compare_if(this);
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForTest(stmt->condition());
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* condition = environment()->Pop();
488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  compare_if.If(condition);
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  compare_if.Then();
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Visit(stmt->then_statement());
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  compare_if.Else();
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Visit(stmt->else_statement());
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  compare_if.End();
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) {
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StructuredGraphBuilder::Environment* env = environment()->CopyAsUnreachable();
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  breakable()->ContinueTarget(stmt->target());
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_environment(env);
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StructuredGraphBuilder::Environment* env = environment()->CopyAsUnreachable();
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  breakable()->BreakTarget(stmt->target());
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_environment(env);
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValue(stmt->expression());
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* result = environment()->Pop();
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* control = NewNode(common()->Return(), result);
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UpdateControlDependencyToLeaveFunction(control);
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitWithStatement(WithStatement* stmt) {
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValue(stmt->expression());
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = environment()->Pop();
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* op = javascript()->CreateWithContext();
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* context = NewNode(op, value, GetFunctionClosure());
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ContextScope scope(this, stmt->scope(), context);
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Visit(stmt->statement());
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<CaseClause*>* clauses = stmt->cases();
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SwitchBuilder compare_switch(this, clauses->length());
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BreakableScope scope(this, stmt, &compare_switch, 0);
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  compare_switch.BeginSwitch();
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int default_index = -1;
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Keep the switch value on the stack until a case matches.
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValue(stmt->tag());
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* tag = environment()->Top();
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Iterate over all cases and create nodes for label comparison.
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < clauses->length(); i++) {
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CaseClause* clause = clauses->at(i);
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The default is not a test, remember index.
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (clause->is_default()) {
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      default_index = i;
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      continue;
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Create nodes to perform label comparison as if via '==='. The switch
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // value is still on the operand stack while the label is evaluated.
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitForValue(clause->label());
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* label = environment()->Pop();
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const Operator* op = javascript()->StrictEqual();
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* condition = NewNode(op, tag, label);
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    compare_switch.BeginLabel(i, condition);
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Discard the switch value at label match.
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    environment()->Pop();
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    compare_switch.EndLabel();
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Discard the switch value and mark the default case.
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Pop();
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (default_index >= 0) {
566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    compare_switch.DefaultAt(default_index);
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Iterate over all cases and create nodes for case bodies.
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < clauses->length(); i++) {
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CaseClause* clause = clauses->at(i);
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    compare_switch.BeginCase(i);
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitStatements(clause->statements());
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    compare_switch.EndCase();
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  compare_switch.EndSwitch();
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LoopBuilder while_loop(this);
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while_loop.BeginLoop();
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitIterationBody(stmt, &while_loop, 0);
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while_loop.EndBody();
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForTest(stmt->cond());
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* condition = environment()->Pop();
588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while_loop.BreakUnless(condition);
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while_loop.EndLoop();
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LoopBuilder while_loop(this);
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while_loop.BeginLoop();
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForTest(stmt->cond());
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* condition = environment()->Pop();
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while_loop.BreakUnless(condition);
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitIterationBody(stmt, &while_loop, 0);
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while_loop.EndBody();
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while_loop.EndLoop();
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitForStatement(ForStatement* stmt) {
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LoopBuilder for_loop(this);
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitIfNotNull(stmt->init());
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for_loop.BeginLoop();
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (stmt->cond() != NULL) {
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitForTest(stmt->cond());
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* condition = environment()->Pop();
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for_loop.BreakUnless(condition);
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitIterationBody(stmt, &for_loop, 0);
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for_loop.EndBody();
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitIfNotNull(stmt->next());
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for_loop.EndLoop();
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(dcarney): this is a big function.  Try to clean up some.
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValue(stmt->subject());
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* obj = environment()->Pop();
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check for undefined or null before entering loop.
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IfBuilder is_undefined(this);
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* is_undefined_cond =
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      NewNode(javascript()->StrictEqual(), obj, jsgraph()->UndefinedConstant());
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  is_undefined.If(is_undefined_cond);
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  is_undefined.Then();
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  is_undefined.Else();
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    IfBuilder is_null(this);
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* is_null_cond =
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        NewNode(javascript()->StrictEqual(), obj, jsgraph()->NullConstant());
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    is_null.If(is_null_cond);
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    is_null.Then();
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    is_null.Else();
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Convert object to jsobject.
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // PrepareForBailoutForId(stmt->PrepareId(), TOS_REG);
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    obj = NewNode(javascript()->ToObject(), obj);
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    environment()->Push(obj);
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(dcarney): should do a fast enum cache check here to skip runtime.
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    environment()->Push(obj);
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* cache_type = ProcessArguments(
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        javascript()->Runtime(Runtime::kGetPropertyNamesFast, 1), 1);
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(dcarney): these next runtime calls should be removed in favour of
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    //                a few simplified instructions.
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    environment()->Push(obj);
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    environment()->Push(cache_type);
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* cache_pair =
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ProcessArguments(javascript()->Runtime(Runtime::kForInInit, 2), 2);
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // cache_type may have been replaced.
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* cache_array = NewNode(common()->Projection(0), cache_pair);
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cache_type = NewNode(common()->Projection(1), cache_pair);
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    environment()->Push(cache_type);
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    environment()->Push(cache_array);
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* cache_length = ProcessArguments(
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        javascript()->Runtime(Runtime::kForInCacheArrayLength, 2), 2);
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // TODO(dcarney): this check is actually supposed to be for the
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //                empty enum case only.
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      IfBuilder have_no_properties(this);
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* empty_array_cond = NewNode(javascript()->StrictEqual(),
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       cache_length, jsgraph()->ZeroConstant());
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      have_no_properties.If(empty_array_cond);
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      have_no_properties.Then();
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Pop obj and skip loop.
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      environment()->Pop();
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      have_no_properties.Else();
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      {
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Construct the rest of the environment.
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        environment()->Push(cache_type);
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        environment()->Push(cache_array);
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        environment()->Push(cache_length);
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        environment()->Push(jsgraph()->ZeroConstant());
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        LoopBuilder for_loop(this);
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for_loop.BeginLoop();
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Check loop termination condition.
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* index = environment()->Peek(0);
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* exit_cond =
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            NewNode(javascript()->LessThan(), index, cache_length);
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // TODO(jarin): provide real bailout id.
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrepareFrameState(exit_cond, BailoutId::None());
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for_loop.BreakUnless(exit_cond);
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // TODO(dcarney): this runtime call should be a handful of
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        //                simplified instructions that
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        //                basically produce
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        //                    value = array[index]
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        environment()->Push(obj);
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        environment()->Push(cache_array);
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        environment()->Push(cache_type);
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        environment()->Push(index);
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* pair =
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            ProcessArguments(javascript()->Runtime(Runtime::kForInNext, 4), 4);
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* value = NewNode(common()->Projection(0), pair);
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* should_filter = NewNode(common()->Projection(1), pair);
699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        environment()->Push(value);
700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        {
701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // Test if FILTER_KEY needs to be called.
702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          IfBuilder test_should_filter(this);
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Node* should_filter_cond =
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              NewNode(javascript()->StrictEqual(), should_filter,
705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      jsgraph()->TrueConstant());
706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          test_should_filter.If(should_filter_cond);
707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          test_should_filter.Then();
708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          value = environment()->Pop();
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Node* builtins = BuildLoadBuiltinsObject();
710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Node* function = BuildLoadObjectField(
711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              builtins,
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              JSBuiltinsObject::OffsetOfFunctionWithId(Builtins::FILTER_KEY));
713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // Callee.
714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          environment()->Push(function);
715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // Receiver.
716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          environment()->Push(obj);
717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // Args.
718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          environment()->Push(value);
719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // result is either the string key or Smi(0) indicating the property
720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // is gone.
721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Node* res = ProcessArguments(
722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              javascript()->Call(3, NO_CALL_FUNCTION_FLAGS), 3);
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // TODO(jarin): provide real bailout id.
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          PrepareFrameState(res, BailoutId::None());
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Node* property_missing = NewNode(javascript()->StrictEqual(), res,
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           jsgraph()->ZeroConstant());
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          {
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            IfBuilder is_property_missing(this);
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            is_property_missing.If(property_missing);
730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            is_property_missing.Then();
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            // Inc counter and continue.
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Node* index_inc =
733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            // TODO(jarin): provide real bailout id.
735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            PrepareFrameState(index_inc, BailoutId::None());
736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            environment()->Poke(0, index_inc);
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            for_loop.Continue();
738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            is_property_missing.Else();
739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            is_property_missing.End();
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // Replace 'value' in environment.
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          environment()->Push(res);
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          test_should_filter.Else();
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          test_should_filter.End();
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        value = environment()->Pop();
747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Bind value and do loop body.
748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        VisitForInAssignment(stmt->each(), value);
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        VisitIterationBody(stmt, &for_loop, 5);
750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for_loop.EndBody();
751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Inc counter and continue.
752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* index_inc =
753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // TODO(jarin): provide real bailout id.
755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrepareFrameState(index_inc, BailoutId::None());
756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        environment()->Poke(0, index_inc);
757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for_loop.EndLoop();
758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        environment()->Drop(5);
759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      have_no_properties.End();
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    is_null.End();
764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  is_undefined.End();
766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) {
770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValue(stmt->subject());
771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Pop();
772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(turbofan): create and use loop builder.
773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(turbofan): Do we really need a separate reloc-info for this?
788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* node = NewNode(javascript()->Runtime(Runtime::kDebugBreak, 0));
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrepareFrameState(node, stmt->DebugBreakId());
790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* context = current_context();
795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Build a new shared function info if we cannot find one in the baseline
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // code. We also have a stack overflow if the recursive compilation did.
798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<SharedFunctionInfo> shared_info =
799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SearchSharedFunctionInfo(info()->shared_info()->code(), expr);
800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (shared_info.is_null()) {
801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    shared_info = Compiler::BuildFunctionInfo(expr, info()->script(), info());
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(!shared_info.is_null());  // TODO(mstarzinger): Set stack overflow?
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create node to instantiate a new closure.
806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* info = jsgraph()->Constant(shared_info);
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* pretenure = expr->pretenure() ? jsgraph()->TrueConstant()
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      : jsgraph()->FalseConstant();
809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* op = javascript()->Runtime(Runtime::kNewClosure, 3);
810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = NewNode(op, context, info, pretenure);
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(value);
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) {
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(arv): Implement.
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitConditional(Conditional* expr) {
827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IfBuilder compare_if(this);
828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForTest(expr->condition());
829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* condition = environment()->Pop();
830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  compare_if.If(condition);
831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  compare_if.Then();
832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Visit(expr->then_expression());
833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  compare_if.Else();
834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Visit(expr->else_expression());
835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  compare_if.End();
836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ReplaceValue();
837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = BuildVariableLoad(expr->var(), expr->id());
842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(value);
843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitLiteral(Literal* expr) {
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = jsgraph()->Constant(expr->value());
848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(value);
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* closure = GetFunctionClosure();
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create node to materialize a regular expression literal.
856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* literals_array =
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* literal_index = jsgraph()->Constant(expr->literal_index());
859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* pattern = jsgraph()->Constant(expr->pattern());
860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* flags = jsgraph()->Constant(expr->flags());
861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* op =
862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      javascript()->Runtime(Runtime::kMaterializeRegExpLiteral, 4);
863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* literal = NewNode(op, literals_array, literal_index, pattern, flags);
864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(literal);
865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* closure = GetFunctionClosure();
870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create node to deep-copy the literal boilerplate.
872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  expr->BuildConstantProperties(isolate());
873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* literals_array =
874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* literal_index = jsgraph()->Constant(expr->literal_index());
876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* constants = jsgraph()->Constant(expr->constant_properties());
877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* flags = jsgraph()->Constant(expr->ComputeFlags());
878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* op = javascript()->Runtime(Runtime::kCreateObjectLiteral, 4);
879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* literal = NewNode(op, literals_array, literal_index, constants, flags);
880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The object is expected on the operand stack during computation of the
882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // property values and is the value of the entire expression.
883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Push(literal);
884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Mark all computed expressions that are bound to a key that is shadowed by
886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // a later occurrence of the same key. For the marked expressions, no store
887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // code is emitted.
888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  expr->CalculateEmitStore(zone());
889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create nodes to store computed values into the literal.
891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AccessorTable accessor_table(zone());
892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < expr->properties()->length(); i++) {
893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ObjectLiteral::Property* property = expr->properties()->at(i);
894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (property->IsCompileTimeValue()) continue;
895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Literal* key = property->key();
897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    switch (property->kind()) {
898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case ObjectLiteral::Property::CONSTANT:
899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        UNREACHABLE();
900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Fall through.
903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case ObjectLiteral::Property::COMPUTED: {
904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // It is safe to use [[Put]] here because the boilerplate already
905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // contains computed properties with an uninitialized value.
906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (key->value()->IsInternalizedString()) {
907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (property->emit_store()) {
908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            VisitForValue(property->value());
909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Node* value = environment()->Pop();
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Unique<Name> name = MakeUnique(key->AsPropertyName());
911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Node* store = NewNode(javascript()->StoreNamed(strict_mode(), name),
912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  literal, value);
913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            PrepareFrameState(store, key->id());
914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          } else {
915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            VisitForEffect(property->value());
916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          break;
918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        environment()->Push(literal);  // Duplicate receiver.
920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        VisitForValue(property->key());
921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        VisitForValue(property->value());
922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* value = environment()->Pop();
923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* key = environment()->Pop();
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* receiver = environment()->Pop();
925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (property->emit_store()) {
926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Node* strict = jsgraph()->Constant(SLOPPY);
927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          const Operator* op = javascript()->Runtime(Runtime::kSetProperty, 4);
928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          NewNode(op, receiver, key, value, strict);
929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case ObjectLiteral::Property::PROTOTYPE: {
933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        environment()->Push(literal);  // Duplicate receiver.
934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        VisitForValue(property->value());
935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* value = environment()->Pop();
936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* receiver = environment()->Pop();
937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (property->emit_store()) {
938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          const Operator* op = javascript()->Runtime(Runtime::kSetPrototype, 2);
939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          NewNode(op, receiver, value);
940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case ObjectLiteral::Property::GETTER:
944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        accessor_table.lookup(key)->second->getter = property->value();
945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case ObjectLiteral::Property::SETTER:
947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        accessor_table.lookup(key)->second->setter = property->value();
948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create nodes to define accessors, using only a single call to the runtime
953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for each pair of corresponding getters and setters.
954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (AccessorTable::Iterator it = accessor_table.begin();
955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       it != accessor_table.end(); ++it) {
956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitForValue(it->first);
957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitForValueOrNull(it->second->getter);
958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitForValueOrNull(it->second->setter);
959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* setter = environment()->Pop();
960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* getter = environment()->Pop();
961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* name = environment()->Pop();
962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* attr = jsgraph()->Constant(NONE);
963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const Operator* op =
964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        javascript()->Runtime(Runtime::kDefineAccessorPropertyUnchecked, 5);
965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* call = NewNode(op, literal, name, getter, setter, attr);
966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrepareFrameState(call, it->first->id());
967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Transform literals that contain functions to fast properties.
970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (expr->has_function()) {
971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const Operator* op = javascript()->Runtime(Runtime::kToFastProperties, 1);
972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NewNode(op, literal);
973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(environment()->Pop());
976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* closure = GetFunctionClosure();
981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create node to deep-copy the literal boilerplate.
983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  expr->BuildConstantElements(isolate());
984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* literals_array =
985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* literal_index = jsgraph()->Constant(expr->literal_index());
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* constants = jsgraph()->Constant(expr->constant_elements());
988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* flags = jsgraph()->Constant(expr->ComputeFlags());
989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* op = javascript()->Runtime(Runtime::kCreateArrayLiteral, 4);
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* literal = NewNode(op, literals_array, literal_index, constants, flags);
991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The array and the literal index are both expected on the operand stack
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // during computation of the element values.
994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Push(literal);
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Push(literal_index);
996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create nodes to evaluate all the non-constant subexpressions and to store
998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // them into the newly cloned array.
999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < expr->values()->length(); i++) {
1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Expression* subexpr = expr->values()->at(i);
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitForValue(subexpr);
1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* value = environment()->Pop();
1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* index = jsgraph()->Constant(i);
1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* store = NewNode(javascript()->StoreProperty(strict_mode()), literal,
1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          index, value);
1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrepareFrameState(store, expr->GetIdForElement(i));
1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Pop();  // Array literal index.
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(environment()->Pop());
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) {
1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(expr->IsValidReferenceExpression());
1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Left-hand side can only be a property, a global or a variable slot.
1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Property* property = expr->AsProperty();
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LhsKind assign_type = DetermineLhsKind(expr);
1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Evaluate LHS expression and store the value.
1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (assign_type) {
1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case VARIABLE: {
1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Variable* var = expr->AsVariableProxy()->var();
1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // TODO(jarin) Fill in the correct bailout id.
1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      BuildVariableAssignment(var, value, Token::ASSIGN, BailoutId::None());
1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case NAMED_PROPERTY: {
1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      environment()->Push(value);
1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForValue(property->obj());
1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* object = environment()->Pop();
1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      value = environment()->Pop();
1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Unique<Name> name =
1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          MakeUnique(property->key()->AsLiteral()->AsPropertyName());
1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* store =
1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          NewNode(javascript()->StoreNamed(strict_mode(), name), object, value);
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // TODO(jarin) Fill in the correct bailout id.
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrepareFrameState(store, BailoutId::None());
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case KEYED_PROPERTY: {
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      environment()->Push(value);
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForValue(property->obj());
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForValue(property->key());
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* key = environment()->Pop();
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* object = environment()->Pop();
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      value = environment()->Pop();
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* store = NewNode(javascript()->StoreProperty(strict_mode()), object,
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            key, value);
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // TODO(jarin) Fill in the correct bailout id.
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrepareFrameState(store, BailoutId::None());
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitAssignment(Assignment* expr) {
1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(expr->target()->IsValidReferenceExpression());
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Left-hand side can only be a property, a global or a variable slot.
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Property* property = expr->target()->AsProperty();
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LhsKind assign_type = DetermineLhsKind(expr->target());
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Evaluate LHS expression.
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (assign_type) {
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case VARIABLE:
1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Nothing to do here.
1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case NAMED_PROPERTY:
1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForValue(property->obj());
1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case KEYED_PROPERTY: {
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForValue(property->obj());
1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForValue(property->key());
1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Evaluate the value and potentially handle compound assignments by loading
1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the left-hand side value and performing a binary operation.
1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (expr->is_compound()) {
1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* old_value = NULL;
1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    switch (assign_type) {
1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case VARIABLE: {
1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Variable* variable = expr->target()->AsVariableProxy()->var();
1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        old_value = BuildVariableLoad(variable, expr->target()->id());
1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case NAMED_PROPERTY: {
1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* object = environment()->Top();
1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Unique<Name> name =
1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            MakeUnique(property->key()->AsLiteral()->AsPropertyName());
1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        old_value = NewNode(javascript()->LoadNamed(name), object);
1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrepareFrameState(old_value, property->LoadId(), kPushOutput);
1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case KEYED_PROPERTY: {
1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* key = environment()->Top();
1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* object = environment()->Peek(1);
1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        old_value = NewNode(javascript()->LoadProperty(), object, key);
1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrepareFrameState(old_value, property->LoadId(), kPushOutput);
1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    environment()->Push(old_value);
1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitForValue(expr->value());
1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* right = environment()->Pop();
1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* left = environment()->Pop();
1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* value = BuildBinaryOp(left, right, expr->binary_op());
1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrepareFrameState(value, expr->binary_operation()->id(), kPushOutput);
1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    environment()->Push(value);
1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitForValue(expr->value());
1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Store the value.
1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = environment()->Pop();
1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (assign_type) {
1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case VARIABLE: {
1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Variable* variable = expr->target()->AsVariableProxy()->var();
1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      BuildVariableAssignment(variable, value, expr->op(),
1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              expr->AssignmentId());
1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case NAMED_PROPERTY: {
1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* object = environment()->Pop();
1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Unique<Name> name =
1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          MakeUnique(property->key()->AsLiteral()->AsPropertyName());
1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* store =
1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          NewNode(javascript()->StoreNamed(strict_mode(), name), object, value);
1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrepareFrameState(store, expr->AssignmentId());
1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case KEYED_PROPERTY: {
1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* key = environment()->Pop();
1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* object = environment()->Pop();
1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* store = NewNode(javascript()->StoreProperty(strict_mode()), object,
1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            key, value);
1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrepareFrameState(store, expr->AssignmentId());
1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(value);
1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitYield(Yield* expr) {
1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValue(expr->generator_object());
1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValue(expr->expression());
1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Pop();
1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Pop();
1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(turbofan): VisitYield
1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitThrow(Throw* expr) {
1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValue(expr->exception());
1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* exception = environment()->Pop();
1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* op = javascript()->Runtime(Runtime::kThrow, 1);
1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = NewNode(op, exception);
1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(value);
1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitProperty(Property* expr) {
1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value;
1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (expr->key()->IsPropertyName()) {
1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitForValue(expr->obj());
1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* object = environment()->Pop();
1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Unique<Name> name = MakeUnique(expr->key()->AsLiteral()->AsPropertyName());
1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = NewNode(javascript()->LoadNamed(name), object);
1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitForValue(expr->obj());
1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitForValue(expr->key());
1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* key = environment()->Pop();
1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* object = environment()->Pop();
1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = NewNode(javascript()->LoadProperty(), object, key);
1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(value);
1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitCall(Call* expr) {
1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* callee = expr->expression();
1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Call::CallType call_type = expr->GetCallType(isolate());
1193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Prepare the callee and the receiver to the function call. This depends on
1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the semantics of the underlying call type.
1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS;
1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* receiver_value = NULL;
1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* callee_value = NULL;
1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool possibly_eval = false;
1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (call_type) {
1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Call::GLOBAL_CALL: {
1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Variable* variable = callee->AsVariableProxy()->var();
1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      callee_value = BuildVariableLoad(variable, expr->expression()->id());
1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      receiver_value = jsgraph()->UndefinedConstant();
1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Call::LOOKUP_SLOT_CALL: {
1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Variable* variable = callee->AsVariableProxy()->var();
1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(variable->location() == Variable::LOOKUP);
1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* name = jsgraph()->Constant(variable->name());
1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      const Operator* op = javascript()->Runtime(Runtime::kLoadLookupSlot, 2);
1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* pair = NewNode(op, current_context(), name);
1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      callee_value = NewNode(common()->Projection(0), pair);
1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      receiver_value = NewNode(common()->Projection(1), pair);
1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Call::PROPERTY_CALL: {
1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Property* property = callee->AsProperty();
1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForValue(property->obj());
1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* object = environment()->Top();
1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (property->key()->IsPropertyName()) {
1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Unique<Name> name =
1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            MakeUnique(property->key()->AsLiteral()->AsPropertyName());
1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        callee_value = NewNode(javascript()->LoadNamed(name), object);
1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        VisitForValue(property->key());
1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* key = environment()->Pop();
1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        callee_value = NewNode(javascript()->LoadProperty(), object, key);
1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrepareFrameState(callee_value, property->LoadId(), kPushOutput);
1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      receiver_value = environment()->Pop();
1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Note that a PROPERTY_CALL requires the receiver to be wrapped into an
1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // object for sloppy callees. This could also be modeled explicitly here,
1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // thereby obsoleting the need for a flag to the call operator.
1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      flags = CALL_AS_METHOD;
1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Call::POSSIBLY_EVAL_CALL:
1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      possibly_eval = true;
1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Fall through.
1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Call::OTHER_CALL:
1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForValue(callee);
1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      callee_value = environment()->Pop();
1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      receiver_value = jsgraph()->UndefinedConstant();
1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The callee and the receiver both have to be pushed onto the operand stack
1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // before arguments are being evaluated.
1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Push(callee_value);
1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Push(receiver_value);
1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Evaluate all arguments to the function call,
1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValues(args);
1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Resolve callee and receiver for a potential direct eval call. This block
1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // will mutate the callee and receiver values pushed onto the environment.
1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (possibly_eval && args->length() > 0) {
1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int arg_count = args->length();
1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Extract callee and source string from the environment.
1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* callee = environment()->Peek(arg_count + 1);
1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* source = environment()->Peek(arg_count - 1);
1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Create node to ask for help resolving potential eval call. This will
1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // provide a fully resolved callee and the corresponding receiver.
1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* function = GetFunctionClosure();
1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* receiver = environment()->Lookup(info()->scope()->receiver());
1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* strict = jsgraph()->Constant(strict_mode());
1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* position = jsgraph()->Constant(info()->scope()->start_position());
1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const Operator* op =
1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        javascript()->Runtime(Runtime::kResolvePossiblyDirectEval, 6);
1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* pair =
1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        NewNode(op, callee, source, function, receiver, strict, position);
1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* new_callee = NewNode(common()->Projection(0), pair);
1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* new_receiver = NewNode(common()->Projection(1), pair);
1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Patch callee and receiver on the environment.
1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    environment()->Poke(arg_count + 1, new_callee);
1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    environment()->Poke(arg_count + 0, new_receiver);
1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create node to perform the function call.
1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* call = javascript()->Call(args->length() + 2, flags);
1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = ProcessArguments(call, args->length() + 2);
1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(value);
1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitCallNew(CallNew* expr) {
1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValue(expr->expression());
1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Evaluate all arguments to the construct call.
1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValues(args);
1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create node to perform the construct call.
1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* call = javascript()->CallNew(args->length() + 1);
1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = ProcessArguments(call, args->length() + 1);
1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(value);
1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) {
1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<String> name = expr->name();
1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The callee and the receiver both have to be pushed onto the operand stack
1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // before arguments are being evaluated.
1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS;
1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* receiver_value = BuildLoadBuiltinsObject();
1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Unique<String> unique = MakeUnique(name);
1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value);
1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft
1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // refuses to optimize functions with jsruntime calls).
1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrepareFrameState(callee_value, BailoutId::None(), kPushOutput);
1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Push(callee_value);
1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Push(receiver_value);
1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Evaluate all arguments to the JS runtime call.
1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValues(args);
1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create node to perform the JS runtime call.
1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* call = javascript()->Call(args->length() + 2, flags);
1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = ProcessArguments(call, args->length() + 2);
1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(value);
1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Runtime::Function* function = expr->function();
1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Handle calls to runtime functions implemented in JavaScript separately as
1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the call follows JavaScript ABI and the callee is statically unknown.
1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (expr->is_jsruntime()) {
1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(function == NULL && expr->name()->length() > 0);
1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return VisitCallJSRuntime(expr);
1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Evaluate all arguments to the runtime call.
1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValues(args);
1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create node to perform the runtime call.
1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Runtime::FunctionId functionId = function->function_id;
1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* call = javascript()->Runtime(functionId, args->length());
1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = ProcessArguments(call, args->length());
1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(value);
1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (expr->op()) {
1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::DELETE:
1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return VisitDelete(expr);
1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::VOID:
1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return VisitVoid(expr);
1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::TYPEOF:
1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return VisitTypeof(expr);
1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::NOT:
1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return VisitNot(expr);
1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(expr->expression()->IsValidReferenceExpression());
1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Left-hand side can only be a property, a global or a variable slot.
1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Property* property = expr->expression()->AsProperty();
1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LhsKind assign_type = DetermineLhsKind(expr->expression());
1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Reserve space for result of postfix operation.
1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_postfix = expr->is_postfix() && !ast_context()->IsEffect();
1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_postfix) environment()->Push(jsgraph()->UndefinedConstant());
1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Evaluate LHS expression and get old value.
1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* old_value = NULL;
1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int stack_depth = -1;
1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (assign_type) {
1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case VARIABLE: {
1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Variable* variable = expr->expression()->AsVariableProxy()->var();
1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      old_value = BuildVariableLoad(variable, expr->expression()->id());
1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      stack_depth = 0;
1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case NAMED_PROPERTY: {
1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForValue(property->obj());
1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* object = environment()->Top();
1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Unique<Name> name =
1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          MakeUnique(property->key()->AsLiteral()->AsPropertyName());
1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      old_value = NewNode(javascript()->LoadNamed(name), object);
1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrepareFrameState(old_value, property->LoadId(), kPushOutput);
1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      stack_depth = 1;
1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case KEYED_PROPERTY: {
1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForValue(property->obj());
1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForValue(property->key());
1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* key = environment()->Top();
1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* object = environment()->Peek(1);
1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      old_value = NewNode(javascript()->LoadProperty(), object, key);
1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrepareFrameState(old_value, property->LoadId(), kPushOutput);
1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      stack_depth = 2;
1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Convert old value into a number.
1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  old_value = NewNode(javascript()->ToNumber(), old_value);
1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Save result for postfix expressions at correct stack depth.
1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_postfix) environment()->Poke(stack_depth, old_value);
1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create node to perform +1/-1 operation.
1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value =
1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op());
1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(jarin) Insert proper bailout id here (will need to change
1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // full code generator).
1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrepareFrameState(value, BailoutId::None());
1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Store the value.
1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (assign_type) {
1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case VARIABLE: {
1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Variable* variable = expr->expression()->AsVariableProxy()->var();
1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      environment()->Push(value);
1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      BuildVariableAssignment(variable, value, expr->op(),
1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              expr->AssignmentId());
1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      environment()->Pop();
1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case NAMED_PROPERTY: {
1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* object = environment()->Pop();
1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Unique<Name> name =
1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          MakeUnique(property->key()->AsLiteral()->AsPropertyName());
1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* store =
1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          NewNode(javascript()->StoreNamed(strict_mode(), name), object, value);
1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      environment()->Push(value);
1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrepareFrameState(store, expr->AssignmentId());
1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      environment()->Pop();
1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case KEYED_PROPERTY: {
1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* key = environment()->Pop();
1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* object = environment()->Pop();
1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* store = NewNode(javascript()->StoreProperty(strict_mode()), object,
1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            key, value);
1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      environment()->Push(value);
1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrepareFrameState(store, expr->AssignmentId());
1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      environment()->Pop();
1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Restore old value for postfix expressions.
1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_postfix) value = environment()->Pop();
1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(value);
1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (expr->op()) {
1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::COMMA:
1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return VisitComma(expr);
1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::OR:
1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::AND:
1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return VisitLogicalExpression(expr);
1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default: {
1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForValue(expr->left());
1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForValue(expr->right());
1479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* right = environment()->Pop();
1480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* left = environment()->Pop();
1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* value = BuildBinaryOp(left, right, expr->op());
1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ast_context()->ProduceValue(value);
1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* op;
1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (expr->op()) {
1492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::EQ:
1493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      op = javascript()->Equal();
1494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::NE:
1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      op = javascript()->NotEqual();
1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::EQ_STRICT:
1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      op = javascript()->StrictEqual();
1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::NE_STRICT:
1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      op = javascript()->StrictNotEqual();
1503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::LT:
1505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      op = javascript()->LessThan();
1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::GT:
1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      op = javascript()->GreaterThan();
1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::LTE:
1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      op = javascript()->LessThanOrEqual();
1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::GTE:
1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      op = javascript()->GreaterThanOrEqual();
1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::INSTANCEOF:
1517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      op = javascript()->InstanceOf();
1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::IN:
1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      op = javascript()->HasProperty();
1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
1523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      op = NULL;
1524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValue(expr->left());
1527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValue(expr->right());
1528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* right = environment()->Pop();
1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* left = environment()->Pop();
1530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = NewNode(op, left, right);
1531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(value);
1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitThisFunction(ThisFunction* expr) {
1537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = GetFunctionClosure();
1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(value);
1539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitSuperReference(SuperReference* expr) {
1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitCaseClause(CaseClause* expr) { UNREACHABLE(); }
1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) {
1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(globals()->is_empty());
1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AstVisitor::VisitDeclarations(declarations);
1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (globals()->is_empty()) return;
1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<FixedArray> data =
1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate()->factory()->NewFixedArray(globals()->length(), TENURED);
1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < globals()->length(); ++i) data->set(i, *globals()->at(i));
1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int encoded_flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) |
1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      DeclareGlobalsNativeFlag::encode(info()->is_native()) |
1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      DeclareGlobalsStrictMode::encode(strict_mode());
1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* flags = jsgraph()->Constant(encoded_flags);
1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* pairs = jsgraph()->Constant(data);
1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* op = javascript()->Runtime(Runtime::kDeclareGlobals, 3);
1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NewNode(op, current_context(), pairs, flags);
1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  globals()->Rewind(0);
1565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitIfNotNull(Statement* stmt) {
1569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (stmt == NULL) return;
1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Visit(stmt);
1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitIterationBody(IterationStatement* stmt,
1575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         LoopBuilder* loop, int drop_extra) {
1576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BreakableScope scope(this, stmt, loop, drop_extra);
1577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Visit(stmt->body());
1578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitDelete(UnaryOperation* expr) {
1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value;
1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (expr->expression()->IsVariableProxy()) {
1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Delete of an unqualified identifier is only allowed in classic mode but
1585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // deleting "this" is allowed in all language modes.
1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Variable* variable = expr->expression()->AsVariableProxy()->var();
1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(strict_mode() == SLOPPY || variable->is_this());
1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = BuildVariableDelete(variable);
1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (expr->expression()->IsProperty()) {
1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Property* property = expr->expression()->AsProperty();
1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitForValue(property->obj());
1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitForValue(property->key());
1593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* key = environment()->Pop();
1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* object = environment()->Pop();
1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = NewNode(javascript()->DeleteProperty(strict_mode()), object, key);
1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitForEffect(expr->expression());
1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = jsgraph()->TrueConstant();
1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(value);
1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitVoid(UnaryOperation* expr) {
1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForEffect(expr->expression());
1606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = jsgraph()->UndefinedConstant();
1607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(value);
1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitTypeof(UnaryOperation* expr) {
1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* operand;
1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (expr->expression()->IsVariableProxy()) {
1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Typeof does not throw a reference error on global variables, hence we
1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // perform a non-contextual load in case the operand is a variable proxy.
1616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Variable* variable = expr->expression()->AsVariableProxy()->var();
1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    operand =
1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        BuildVariableLoad(variable, expr->expression()->id(), NOT_CONTEXTUAL);
1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitForValue(expr->expression());
1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    operand = environment()->Pop();
1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = NewNode(javascript()->TypeOf(), operand);
1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(value);
1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitNot(UnaryOperation* expr) {
1629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValue(expr->expression());
1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* operand = environment()->Pop();
1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(mstarzinger): Possible optimization when we are in effect context.
1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = NewNode(javascript()->UnaryNot(), operand);
1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ProduceValue(value);
1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitComma(BinaryOperation* expr) {
1638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForEffect(expr->left());
1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Visit(expr->right());
1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ReplaceValue();
1641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) {
1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_logical_and = expr->op() == Token::AND;
1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IfBuilder compare_if(this);
1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForValue(expr->left());
1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* condition = environment()->Top();
1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  compare_if.If(BuildToBoolean(condition));
1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  compare_if.Then();
1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_logical_and) {
1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    environment()->Pop();
1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Visit(expr->right());
1654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (ast_context()->IsEffect()) {
1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    environment()->Pop();
1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  compare_if.Else();
1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!is_logical_and) {
1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    environment()->Pop();
1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Visit(expr->right());
1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (ast_context()->IsEffect()) {
1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    environment()->Pop();
1663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  compare_if.End();
1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ast_context()->ReplaceValue();
1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) {
1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(environment()->stack_height() >= arity);
1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node** all = info()->zone()->NewArray<Node*>(arity);
1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = arity - 1; i >= 0; --i) {
1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    all[i] = environment()->Pop();
1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = NewNode(op, arity, all);
1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return value;
1677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) {
1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (heap_slots <= 0) return context;
1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_current_context(context);
1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate a new local context.
1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* op = javascript()->CreateFunctionContext();
1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* local_context = NewNode(op, closure);
1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_current_context(local_context);
1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Copy parameters into context if necessary.
1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int num_parameters = info()->scope()->num_parameters();
1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < num_parameters; i++) {
1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Variable* variable = info()->scope()->parameter(i);
1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!variable->IsContextSlot()) continue;
1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Temporary parameter node. The parameter indices are shifted by 1
1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // (receiver is parameter index -1 but environment index 0).
1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start());
1698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Context variable (at bottom of the context chain).
1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope()));
1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const Operator* op = javascript()->StoreContext(0, variable->index());
1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NewNode(op, local_context, parameter);
1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return local_context;
1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) {
1709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (arguments == NULL) return NULL;
1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate and initialize a new arguments object.
1712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* callee = GetFunctionClosure();
1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* op = javascript()->Runtime(Runtime::kNewArguments, 1);
1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* object = NewNode(op, callee);
1715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Assign the object to the arguments variable.
1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated());
1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This should never lazy deopt, so it is fine to send invalid bailout id.
1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BuildVariableAssignment(arguments, object, Token::ASSIGN, BailoutId::None());
1720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return object;
1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole,
1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            Node* not_hole) {
1727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IfBuilder hole_check(this);
1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* the_hole = jsgraph()->TheHoleConstant();
1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* check = NewNode(javascript()->StrictEqual(), value, the_hole);
1730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  hole_check.If(check);
1731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  hole_check.Then();
1732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Push(for_hole);
1733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  hole_check.Else();
1734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Push(not_hole);
1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  hole_check.End();
1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return environment()->Pop();
1737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::BuildHoleCheckThrow(Node* value, Variable* variable,
1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           Node* not_hole) {
1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IfBuilder hole_check(this);
1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* the_hole = jsgraph()->TheHoleConstant();
1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* check = NewNode(javascript()->StrictEqual(), value, the_hole);
1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  hole_check.If(check);
1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  hole_check.Then();
1747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Push(BuildThrowReferenceError(variable));
1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  hole_check.Else();
1749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  environment()->Push(not_hole);
1750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  hole_check.End();
1751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return environment()->Pop();
1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::BuildVariableLoad(Variable* variable,
1756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         BailoutId bailout_id,
1757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         ContextualMode contextual_mode) {
1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* the_hole = jsgraph()->TheHoleConstant();
1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VariableMode mode = variable->mode();
1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (variable->location()) {
1761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::UNALLOCATED: {
1762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Global var, const, or let variable.
1763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* global = BuildLoadGlobalObject();
1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Unique<Name> name = MakeUnique(variable->name());
1765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      const Operator* op = javascript()->LoadNamed(name, contextual_mode);
1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* node = NewNode(op, global);
1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrepareFrameState(node, bailout_id, kPushOutput);
1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return node;
1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::PARAMETER:
1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::LOCAL: {
1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Local var, const, or let variable.
1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* value = environment()->Lookup(variable);
1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (mode == CONST_LEGACY) {
1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Perform check for uninitialized legacy const variables.
1776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (value->op() == the_hole->op()) {
1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          value = jsgraph()->UndefinedConstant();
1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else if (value->opcode() == IrOpcode::kPhi) {
1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Node* undefined = jsgraph()->UndefinedConstant();
1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          value = BuildHoleCheckSilent(value, undefined, value);
1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (mode == LET || mode == CONST) {
1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Perform check for uninitialized let/const variables.
1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (value->op() == the_hole->op()) {
1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          value = BuildThrowReferenceError(variable);
1786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else if (value->opcode() == IrOpcode::kPhi) {
1787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          value = BuildHoleCheckThrow(value, variable, value);
1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return value;
1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::CONTEXT: {
1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Context variable (potentially up the context chain).
1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int depth = current_scope()->ContextChainLength(variable->scope());
1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bool immutable = variable->maybe_assigned() == kNotAssigned;
1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      const Operator* op =
1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          javascript()->LoadContext(depth, variable->index(), immutable);
1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* value = NewNode(op, current_context());
1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // TODO(titzer): initialization checks are redundant for already
1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // initialized immutable context loads, but only specialization knows.
1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Maybe specializer should be a parameter to the graph builder?
1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (mode == CONST_LEGACY) {
1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Perform check for uninitialized legacy const variables.
1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* undefined = jsgraph()->UndefinedConstant();
1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        value = BuildHoleCheckSilent(value, undefined, value);
1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (mode == LET || mode == CONST) {
1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Perform check for uninitialized let/const variables.
1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        value = BuildHoleCheckThrow(value, variable, value);
1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return value;
1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::LOOKUP: {
1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Dynamic lookup of context variable (anywhere in the chain).
1814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* name = jsgraph()->Constant(variable->name());
1815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Runtime::FunctionId function_id =
1816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          (contextual_mode == CONTEXTUAL)
1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              ? Runtime::kLoadLookupSlot
1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              : Runtime::kLoadLookupSlotNoReferenceError;
1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      const Operator* op = javascript()->Runtime(function_id, 2);
1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* pair = NewNode(op, current_context(), name);
1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return NewNode(common()->Projection(0), pair);
1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::BuildVariableDelete(Variable* variable) {
1830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (variable->location()) {
1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::UNALLOCATED: {
1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Global var, const, or let variable.
1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* global = BuildLoadGlobalObject();
1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* name = jsgraph()->Constant(variable->name());
1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      const Operator* op = javascript()->DeleteProperty(strict_mode());
1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return NewNode(op, global, name);
1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::PARAMETER:
1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::LOCAL:
1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::CONTEXT:
1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Local var, const, or let variable or context variable.
1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return variable->is_this() ? jsgraph()->TrueConstant()
1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 : jsgraph()->FalseConstant();
1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::LOOKUP: {
1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Dynamic lookup of context variable (anywhere in the chain).
1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* name = jsgraph()->Constant(variable->name());
1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      const Operator* op = javascript()->Runtime(Runtime::kDeleteLookupSlot, 2);
1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return NewNode(op, current_context(), name);
1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value,
1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               Token::Value op,
1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               BailoutId bailout_id) {
1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* the_hole = jsgraph()->TheHoleConstant();
1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VariableMode mode = variable->mode();
1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (variable->location()) {
1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::UNALLOCATED: {
1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Global var, const, or let variable.
1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* global = BuildLoadGlobalObject();
1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Unique<Name> name = MakeUnique(variable->name());
1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      const Operator* op = javascript()->StoreNamed(strict_mode(), name);
1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* store = NewNode(op, global, value);
1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrepareFrameState(store, bailout_id);
1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return store;
1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::PARAMETER:
1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::LOCAL:
1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Local var, const, or let variable.
1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) {
1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Perform an initialization check for legacy const variables.
1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* current = environment()->Lookup(variable);
1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (current->op() != the_hole->op()) {
1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          value = BuildHoleCheckSilent(current, value, current);
1879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) {
1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Non-initializing assignments to legacy const is ignored.
1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return value;
1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (mode == LET && op != Token::INIT_LET) {
1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Perform an initialization check for let declared variables.
1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Also note that the dynamic hole-check is only done to ensure that
1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // this does not break in the presence of do-expressions within the
1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // temporal dead zone of a let declared variable.
1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* current = environment()->Lookup(variable);
1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (current->op() == the_hole->op()) {
1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          value = BuildThrowReferenceError(variable);
1891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else if (value->opcode() == IrOpcode::kPhi) {
1892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          value = BuildHoleCheckThrow(current, variable, value);
1893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (mode == CONST && op != Token::INIT_CONST) {
1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // All assignments to const variables are early errors.
1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        UNREACHABLE();
1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      environment()->Bind(variable, value);
1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return value;
1900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::CONTEXT: {
1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Context variable (potentially up the context chain).
1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int depth = current_scope()->ContextChainLength(variable->scope());
1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) {
1904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Perform an initialization check for legacy const variables.
1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        const Operator* op =
1906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            javascript()->LoadContext(depth, variable->index(), false);
1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* current = NewNode(op, current_context());
1908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        value = BuildHoleCheckSilent(current, value, current);
1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) {
1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Non-initializing assignments to legacy const is ignored.
1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return value;
1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (mode == LET && op != Token::INIT_LET) {
1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Perform an initialization check for let declared variables.
1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        const Operator* op =
1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            javascript()->LoadContext(depth, variable->index(), false);
1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Node* current = NewNode(op, current_context());
1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        value = BuildHoleCheckThrow(current, variable, value);
1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (mode == CONST && op != Token::INIT_CONST) {
1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // All assignments to const variables are early errors.
1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        UNREACHABLE();
1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      const Operator* op = javascript()->StoreContext(depth, variable->index());
1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return NewNode(op, current_context(), value);
1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Variable::LOOKUP: {
1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Dynamic lookup of context variable (anywhere in the chain).
1927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* name = jsgraph()->Constant(variable->name());
1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* strict = jsgraph()->Constant(strict_mode());
1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for
1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // initializations of const declarations.
1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      const Operator* op = javascript()->Runtime(Runtime::kStoreLookupSlot, 4);
1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return NewNode(op, value, current_context(), name, strict);
1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(sigurds) Use simplified load here once it is ready.
1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* field_load = NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object,
1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             jsgraph()->Int32Constant(offset - kHeapObjectTag));
1944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return field_load;
1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::BuildLoadBuiltinsObject() {
1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* global = BuildLoadGlobalObject();
1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* builtins =
1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset);
1952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return builtins;
1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::BuildLoadGlobalObject() {
1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* context = GetFunctionContext();
1958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* load_op =
1959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true);
1960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NewNode(load_op, context);
1961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::BuildToBoolean(Node* value) {
1965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(mstarzinger): Possible optimization is to NOP for boolean values.
1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NewNode(javascript()->ToBoolean(), value);
1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::BuildThrowReferenceError(Variable* variable) {
1971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(mstarzinger): Should be unified with the VisitThrow implementation.
1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* variable_name = jsgraph()->Constant(variable->name());
1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* op = javascript()->Runtime(Runtime::kThrowReferenceError, 1);
1974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NewNode(op, variable_name);
1975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op) {
1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* js_op;
1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (op) {
1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::BIT_OR:
1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      js_op = javascript()->BitwiseOr();
1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::BIT_AND:
1985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      js_op = javascript()->BitwiseAnd();
1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::BIT_XOR:
1988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      js_op = javascript()->BitwiseXor();
1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::SHL:
1991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      js_op = javascript()->ShiftLeft();
1992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::SAR:
1994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      js_op = javascript()->ShiftRight();
1995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::SHR:
1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      js_op = javascript()->ShiftRightLogical();
1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::ADD:
2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      js_op = javascript()->Add();
2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::SUB:
2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      js_op = javascript()->Subtract();
2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::MUL:
2006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      js_op = javascript()->Multiply();
2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::DIV:
2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      js_op = javascript()->Divide();
2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
2011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::MOD:
2012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      js_op = javascript()->Modulus();
2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
2015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
2016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      js_op = NULL;
2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NewNode(js_op, left, right);
2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id,
2023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        OutputFrameStateCombine combine) {
2024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (OperatorProperties::HasFrameStateInput(node->op())) {
2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(NodeProperties::GetFrameStateInput(node)->opcode() ==
2026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           IrOpcode::kDead);
2027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NodeProperties::ReplaceFrameStateInput(
2028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        node, environment()->Checkpoint(ast_id, combine));
2029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8::internal::compiler
2035