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(¶meters_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