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 7f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/ast/compile-time-value.h" 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/scopes.h" 9f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/compilation-info.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler.h" 11958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/ast-loop-assignment-analyzer.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/control-builders.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/linkage.h" 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/liveness-analyzer.h" 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/machine-operator.h" 16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/node-matchers.h" 17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/node-properties.h" 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/operator-properties.h" 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/state-values-utils.h" 2062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/feedback-vector.h" 2162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h" 2262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects/literal-objects.h" 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler { 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Each expression in the AST is evaluated in a specific context. This context 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// decides how the evaluation result is passed up the visitor. 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass AstGraphBuilder::AstContext BASE_EMBEDDED { 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsEffect() const { return kind_ == Expression::kEffect; } 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsValue() const { return kind_ == Expression::kValue; } 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsTest() const { return kind_ == Expression::kTest; } 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Determines how to combine the frame state with the value 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // that is about to be plugged into this AstContext. 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutputFrameStateCombine GetStateCombine() { 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return IsEffect() ? OutputFrameStateCombine::Ignore() 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : OutputFrameStateCombine::Push(); 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Plug a node into this expression context. Call this function in tail 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // position in the Visit functions for expressions. 46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch virtual void ProduceValue(Expression* expr, Node* value) = 0; 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Unplugs a node from this expression context. Call this to retrieve the 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // result of another Visit function that already plugged the context. 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual Node* ConsumeValue() = 0; 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Shortcut for "context->ProduceValue(context->ConsumeValue())". 53f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ReplaceValue(Expression* expr) { ProduceValue(expr, ConsumeValue()); } 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch protected: 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AstContext(AstGraphBuilder* owner, Expression::Context kind); 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual ~AstContext(); 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AstGraphBuilder* owner() const { return owner_; } 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Environment* environment() const { return owner_->environment(); } 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// We want to be able to assert, in a context-specific way, that the stack 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// height makes sense when the context is filled. 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef DEBUG 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int original_height_; 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Expression::Context kind_; 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AstGraphBuilder* owner_; 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AstContext* outer_; 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Context to evaluate expression for its side effects only. 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass AstGraphBuilder::AstEffectContext final : public AstContext { 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit AstEffectContext(AstGraphBuilder* owner) 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : AstContext(owner, Expression::kEffect) {} 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ~AstEffectContext() final; 81f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ProduceValue(Expression* expr, Node* value) final; 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* ConsumeValue() final; 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Context to evaluate expression for its value (and side effects). 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass AstGraphBuilder::AstValueContext final : public AstContext { 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit AstValueContext(AstGraphBuilder* owner) 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : AstContext(owner, Expression::kValue) {} 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ~AstValueContext() final; 92f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ProduceValue(Expression* expr, Node* value) final; 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* ConsumeValue() final; 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Context to evaluate expression for a condition value (and side effects). 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass AstGraphBuilder::AstTestContext final : public AstContext { 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AstTestContext(AstGraphBuilder* owner, TypeFeedbackId feedback_id) 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : AstContext(owner, Expression::kTest), feedback_id_(feedback_id) {} 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ~AstTestContext() final; 103f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ProduceValue(Expression* expr, Node* value) final; 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* ConsumeValue() final; 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TypeFeedbackId const feedback_id_; 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Scoped class tracking context objects created by the visitor. Represents 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// mutations of the context chain within the function body and allows to 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// change the current {scope} and {context} during visitation. 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass AstGraphBuilder::ContextScope BASE_EMBEDDED { 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ContextScope(AstGraphBuilder* builder, Scope* scope, Node* context) 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : builder_(builder), 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch outer_(builder->execution_context()), 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch scope_(scope), 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch depth_(builder_->environment()->context_chain_length()) { 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder_->environment()->PushContext(context); // Push. 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder_->set_execution_context(this); 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ~ContextScope() { 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder_->set_execution_context(outer_); // Pop. 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder_->environment()->PopContext(); 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_EQ(depth_, builder_->environment()->context_chain_length()); 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Current scope during visitation. 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Scope* scope() const { return scope_; } 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AstGraphBuilder* builder_; 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ContextScope* outer_; 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Scope* scope_; 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int depth_; 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Scoped class tracking control statements entered by the visitor. There are 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// different types of statements participating in this stack to properly track 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// local as well as non-local control flow: 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// - IterationStatement : Allows proper 'break' and 'continue' behavior. 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// - BreakableStatement : Allows 'break' from block and switch statements. 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// - TryCatchStatement : Intercepts 'throw' and implicit exceptional edges. 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// - TryFinallyStatement: Intercepts 'break', 'continue', 'throw' and 'return'. 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass AstGraphBuilder::ControlScope BASE_EMBEDDED { 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit ControlScope(AstGraphBuilder* builder) 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : builder_(builder), 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch outer_(builder->execution_control()), 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch context_length_(builder->environment()->context_chain_length()), 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stack_height_(builder->environment()->stack_height()) { 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder_->set_execution_control(this); // Push. 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual ~ControlScope() { 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder_->set_execution_control(outer_); // Pop. 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Either 'break' or 'continue' to the target statement. 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BreakTo(BreakableStatement* target); 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ContinueTo(BreakableStatement* target); 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Either 'return' or 'throw' the given value. 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ReturnValue(Node* return_value); 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ThrowValue(Node* exception_value); 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch protected: 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum Command { CMD_BREAK, CMD_CONTINUE, CMD_RETURN, CMD_THROW }; 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Performs one of the above commands on this stack of control scopes. This 175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // walks through the stack giving each scope a chance to execute or defer the 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // given command by overriding the {Execute} method appropriately. Note that 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // this also drops extra operands from the environment for each skipped scope. 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void PerformCommand(Command cmd, Statement* target, Node* value); 179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Interface to execute a given command in this scope. Returning {true} here 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // indicates successful execution whereas {false} requests to skip scope. 182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch virtual bool Execute(Command cmd, Statement* target, Node** value) { 183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // For function-level control. 184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (cmd) { 185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case CMD_THROW: 186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch builder()->BuildThrow(*value); 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case CMD_RETURN: 189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch builder()->BuildReturn(*value); 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case CMD_BREAK: 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case CMD_CONTINUE: 193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Environment* environment() { return builder_->environment(); } 199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AstGraphBuilder* builder() const { return builder_; } 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int context_length() const { return context_length_; } 201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int stack_height() const { return stack_height_; } 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AstGraphBuilder* builder_; 205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ControlScope* outer_; 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int context_length_; 207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int stack_height_; 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Control scope implementation for a BreakableStatement. 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass AstGraphBuilder::ControlScopeForBreakable : public ControlScope { 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ControlScopeForBreakable(AstGraphBuilder* owner, BreakableStatement* target, 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ControlBuilder* control) 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : ControlScope(owner), target_(target), control_(control) {} 217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch protected: 219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool Execute(Command cmd, Statement* target, Node** value) override { 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (target != target_) return false; // We are not the command target. 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (cmd) { 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case CMD_BREAK: 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch control_->Break(); 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case CMD_CONTINUE: 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case CMD_THROW: 227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case CMD_RETURN: 228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BreakableStatement* target_; 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ControlBuilder* control_; 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Control scope implementation for an IterationStatement. 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass AstGraphBuilder::ControlScopeForIteration : public ControlScope { 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ControlScopeForIteration(AstGraphBuilder* owner, IterationStatement* target, 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoopBuilder* control) 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : ControlScope(owner), target_(target), control_(control) {} 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch protected: 247f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool Execute(Command cmd, Statement* target, Node** value) override { 248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (target != target_) { 249f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch control_->ExitLoop(value); 250f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 251f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (cmd) { 253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case CMD_BREAK: 254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch control_->Break(); 255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case CMD_CONTINUE: 257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch control_->Continue(); 258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case CMD_THROW: 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case CMD_RETURN: 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BreakableStatement* target_; 268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoopBuilder* control_; 269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierAstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info, 273f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch JSGraph* jsgraph, float invocation_frequency, 27462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch LoopAssignmentAnalysis* loop) 275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : isolate_(info->isolate()), 276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch local_zone_(local_zone), 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info_(info), 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jsgraph_(jsgraph), 279f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch invocation_frequency_(invocation_frequency), 280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment_(nullptr), 281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ast_context_(nullptr), 282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier globals_(0, local_zone), 283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch execution_control_(nullptr), 284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch execution_context_(nullptr), 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch input_buffer_size_(0), 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch input_buffer_(nullptr), 287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch exit_controls_(local_zone), 288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch loop_assignment_analysis_(loop), 289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch state_values_cache_(jsgraph), 290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()), 291c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch false, local_zone), 292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_state_function_info_(common()->CreateFrameStateFunctionInfo( 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrameStateType::kJavaScriptFunction, info->num_parameters() + 1, 294109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch info->scope()->num_stack_slots(), info->shared_info())) { 295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InitializeAstVisitor(info->isolate()); 296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::GetFunctionClosureForContext() { 300f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeclarationScope* closure_scope = current_scope()->GetClosureScope(); 301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (closure_scope->is_script_scope() || 302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch closure_scope->is_module_scope()) { 303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Contexts nested in the native context have a canonical empty function as 304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // their closure, not the anonymous closure containing the global code. 305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return BuildLoadNativeContextField(Context::CLOSURE_INDEX); 306bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (closure_scope->is_eval_scope()) { 307bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Contexts nested inside eval code have the same closure as the context 308bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // calling eval, not the anonymous closure containing the eval code. 309bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch const Operator* op = 310bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch javascript()->LoadContext(0, Context::CLOSURE_INDEX, false); 31162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return NewNode(op); 312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(closure_scope->is_function_scope()); 314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return GetFunctionClosure(); 315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::GetFunctionClosure() { 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!function_closure_.is_set()) { 321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int index = Linkage::kJSCallClosureParamIndex; 322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = common()->Parameter(index, "%closure"); 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* node = NewNode(op, graph()->start()); 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_closure_.set(node); 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return function_closure_.get(); 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::GetFunctionContext() { 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!function_context_.is_set()) { 332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int params = info()->num_parameters_including_this(); 333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int index = Linkage::GetJSCallContextParamIndex(params); 334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = common()->Parameter(index, "%context"); 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* node = NewNode(op, graph()->start()); 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_context_.set(node); 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return function_context_.get(); 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 34113e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochNode* AstGraphBuilder::GetEmptyFrameState() { 34213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!empty_frame_state_.is_set()) { 34313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch const Operator* op = common()->FrameState( 34413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch BailoutId::None(), OutputFrameStateCombine::Ignore(), nullptr); 34513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* node = graph()->NewNode( 34613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch op, jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), 34713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch jsgraph()->EmptyStateValues(), jsgraph()->NoContextConstant(), 34813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch jsgraph()->UndefinedConstant(), graph()->start()); 34913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch empty_frame_state_.set(node); 35013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 35113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return empty_frame_state_.get(); 35213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool AstGraphBuilder::CreateGraph(bool stack_check) { 355f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeclarationScope* scope = info()->scope(); 356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NOT_NULL(graph()); 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Set up the basic structure of the graph. Outputs for {Start} are the formal 359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // parameters (including the receiver) plus new target, number of arguments, 360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // context and closure. 361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int actual_parameter_count = info()->num_parameters_including_this() + 4; 362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count))); 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize the top-level environment. 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Environment env(this, scope, graph()->start()); 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_environment(&env); 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info()->is_osr()) { 369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Use OSR normal entry as the start of the top-level environment. 370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // It will be replaced with {Dead} after typing and optimizations. 371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NewNode(common()->OsrNormalEntry()); 372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Initialize the incoming context. 375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ContextScope incoming(this, scope, GetFunctionContext()); 376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Initialize control scope. 378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ControlScope control(this); 379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(mstarzinger): For now we cannot assume that the {this} parameter is 381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // not {the_hole}, because for derived classes {this} has a TDZ and the 382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // JSConstructStubForDerived magically passes {the_hole} as a receiver. 383f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (scope->has_this_declaration() && scope->receiver()->mode() == CONST) { 384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch env.RawParameterBind(0, jsgraph()->TheHoleConstant()); 385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 387f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (scope->NeedsContext()) { 388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Push a new inner context scope for the current activation. 389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* inner_context = BuildLocalActivationContext(GetFunctionContext()); 390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ContextScope top_context(this, scope, inner_context); 391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CreateGraphBody(stack_check); 392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Simply use the outer function context in building the graph. 394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CreateGraphBody(stack_check); 395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Finish the basic structure of the graph. 398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, exit_controls_.size()); 399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int const input_count = static_cast<int>(exit_controls_.size()); 400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node** const inputs = &exit_controls_.front(); 401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs); 402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->SetEnd(end); 403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compute local variable liveness information and use it to relax 405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // frame states. 406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ClearNonLiveSlotsInFrameStates(); 407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Failures indicated by stack overflow. 409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return !HasStackOverflow(); 410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::CreateGraphBody(bool stack_check) { 414f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeclarationScope* scope = info()->scope(); 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Build the arguments object if it is used. 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BuildArgumentsObject(scope->arguments()); 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 41962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // We don't support new.target and rest parameters here. 42062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_NULL(scope->new_target_var()); 42162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_NULL(scope->rest_parameter()); 42262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_NULL(scope->this_function_var()); 423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit tracing call if requested to do so. 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace) { 426109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch NewNode(javascript()->CallRuntime(Runtime::kTraceEnter)); 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Visit declarations within the function scope. 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitDeclarations(scope->declarations()); 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Build a stack-check before the body. 433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (stack_check) { 434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* node = NewNode(javascript()->StackCheck()); 435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrepareFrameState(node, BailoutId::FunctionEntry()); 436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Visit statements in the function body. 439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitStatements(info()->literal()->body()); 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return 'undefined' in case we can fall off the end. 442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildReturn(jsgraph()->UndefinedConstant()); 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::ClearNonLiveSlotsInFrameStates() { 447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!FLAG_analyze_environment_liveness || 448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch !info()->is_deoptimization_enabled()) { 449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NonLiveFrameStateSlotReplacer replacer( 4533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch &state_values_cache_, jsgraph()->OptimizedOutConstant(), 454c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch liveness_analyzer()->local_count(), false, local_zone()); 455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Variable* arguments = info()->scope()->arguments(); 456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (arguments != nullptr && arguments->IsStackAllocated()) { 457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch replacer.MarkPermanentlyLive(arguments->index()); 458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch liveness_analyzer()->Run(&replacer); 460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_trace_environment_liveness) { 461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OFStream os(stdout); 462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch liveness_analyzer()->Print(os); 463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Gets the bailout id just before reading a variable proxy, but only for 468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// unallocated variables. 469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic BailoutId BeforeId(VariableProxy* proxy) { 470f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return proxy->var()->IsUnallocated() ? proxy->BeforeId() : BailoutId::None(); 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 473f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstatic const char* GetDebugParameterName(Zone* zone, DeclarationScope* scope, 474f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int index) { 475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if DEBUG 476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const AstRawString* name = scope->parameter(index)->raw_name(); 477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (name && name->length() > 0) { 478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch char* data = zone->NewArray<char>(name->length() + 1); 479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch data[name->length()] = 0; 480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch memcpy(data, name->raw_data(), name->length()); 481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return data; 482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return nullptr; 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstGraphBuilder::Environment::Environment(AstGraphBuilder* builder, 488f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeclarationScope* scope, 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* control_dependency) 490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : builder_(builder), 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch parameters_count_(scope->num_parameters() + 1), 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch locals_count_(scope->num_stack_slots()), 493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch liveness_block_(IsLivenessAnalysisEnabled() 494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? builder_->liveness_analyzer()->NewBlock() 495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : nullptr), 496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch values_(builder_->local_zone()), 497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch contexts_(builder_->local_zone()), 498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch control_dependency_(control_dependency), 499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch effect_dependency_(control_dependency), 500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parameters_node_(nullptr), 501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch locals_node_(nullptr), 502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stack_node_(nullptr) { 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(scope->num_parameters() + 1, parameters_count()); 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bind the receiver variable. 506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int param_num = 0; 507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (builder->info()->is_this_defined()) { 508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = common()->Parameter(param_num++, "%this"); 509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* receiver = builder->graph()->NewNode(op, builder->graph()->start()); 510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch values()->push_back(receiver); 511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch values()->push_back(builder->jsgraph()->UndefinedConstant()); 513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bind all parameter variables. The parameter indices are shifted by 1 516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // (receiver is variable index -1 but {Parameter} node index 0 and located at 517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // index 0 in the environment). 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < scope->num_parameters(); ++i) { 519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const char* debug_name = GetDebugParameterName(graph()->zone(), scope, i); 520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = common()->Parameter(param_num++, debug_name); 521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* parameter = builder->graph()->NewNode(op, builder->graph()->start()); 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values()->push_back(parameter); 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bind all local variables to undefined. 526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values()->insert(values()->end(), locals_count(), undefined_constant); 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAstGraphBuilder::Environment::Environment(AstGraphBuilder::Environment* copy, 532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LivenessAnalyzerBlock* liveness_block) 533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : builder_(copy->builder_), 534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parameters_count_(copy->parameters_count_), 535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch locals_count_(copy->locals_count_), 536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch liveness_block_(liveness_block), 537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch values_(copy->zone()), 538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch contexts_(copy->zone()), 539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch control_dependency_(copy->control_dependency_), 540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch effect_dependency_(copy->effect_dependency_), 541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parameters_node_(copy->parameters_node_), 542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch locals_node_(copy->locals_node_), 543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stack_node_(copy->stack_node_) { 544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const size_t kStackEstimate = 7; // optimum from experimentation! 545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch values_.reserve(copy->values_.size() + kStackEstimate); 546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch values_.insert(values_.begin(), copy->values_.begin(), copy->values_.end()); 547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch contexts_.reserve(copy->contexts_.size()); 548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch contexts_.insert(contexts_.begin(), copy->contexts_.begin(), 549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch copy->contexts_.end()); 550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::Environment::Bind(Variable* variable, Node* node) { 554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(variable->IsStackAllocated()); 555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (variable->IsParameter()) { 556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The parameter indices are shifted by 1 (receiver is variable 557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // index -1 but located at index 0 in the environment). 558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch values()->at(variable->index() + 1) = node; 559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(variable->IsStackLocal()); 561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch values()->at(variable->index() + parameters_count_) = node; 562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsLivenessBlockConsistent()); 563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (liveness_block() != nullptr) { 564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch liveness_block()->Bind(variable->index()); 565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::Environment::Lookup(Variable* variable) { 571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(variable->IsStackAllocated()); 572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (variable->IsParameter()) { 573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The parameter indices are shifted by 1 (receiver is variable 574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // index -1 but located at index 0 in the environment). 575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return values()->at(variable->index() + 1); 576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(variable->IsStackLocal()); 578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsLivenessBlockConsistent()); 579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (liveness_block() != nullptr) { 580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch liveness_block()->Lookup(variable->index()); 581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return values()->at(variable->index() + parameters_count_); 583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::Environment::MarkAllLocalsLive() { 588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsLivenessBlockConsistent()); 589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (liveness_block() != nullptr) { 590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < locals_count_; i++) { 591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch liveness_block()->Lookup(i); 592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::Environment::RawParameterBind(int index, Node* node) { 598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_LT(index, parameters_count()); 599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch values()->at(index) = node; 600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::Environment::RawParameterLookup(int index) { 604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_LT(index, parameters_count()); 605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return values()->at(index); 606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAstGraphBuilder::Environment* 610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAstGraphBuilder::Environment::CopyForConditional() { 611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LivenessAnalyzerBlock* copy_liveness_block = nullptr; 612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (liveness_block() != nullptr) { 613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch copy_liveness_block = 614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder_->liveness_analyzer()->NewBlock(liveness_block()); 615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block()); 616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return new (zone()) Environment(this, copy_liveness_block); 618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAstGraphBuilder::Environment* 622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAstGraphBuilder::Environment::CopyAsUnreachable() { 623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Environment* env = new (zone()) Environment(this, nullptr); 624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch env->MarkAsUnreachable(); 625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return env; 626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 628f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstGraphBuilder::Environment* AstGraphBuilder::Environment::CopyForOsrEntry() { 629c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch LivenessAnalyzerBlock* copy_block = 630c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch liveness_block() == nullptr ? nullptr 631c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch : builder_->liveness_analyzer()->NewBlock(); 632c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return new (zone()) Environment(this, copy_block); 633f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAstGraphBuilder::Environment* 636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAstGraphBuilder::Environment::CopyAndShareLiveness() { 637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (liveness_block() != nullptr) { 638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Finish the current liveness block before copying. 639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block()); 640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Environment* env = new (zone()) Environment(this, liveness_block()); 642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return env; 643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAstGraphBuilder::Environment* AstGraphBuilder::Environment::CopyForLoop( 647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BitVector* assigned, bool is_osr) { 648f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch PrepareForLoop(assigned); 649f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Environment* loop = CopyAndShareLiveness(); 650f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (is_osr) { 651f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Create and merge the OSR entry if necessary. 652f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Environment* osr_env = CopyForOsrEntry(); 653f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch osr_env->PrepareForOsrEntry(); 654f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch loop->Merge(osr_env); 655f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 656f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return loop; 657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::Environment::UpdateStateValues(Node** state_values, 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset, int count) { 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool should_update = false; 663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node** env_values = (count == 0) ? nullptr : &values()->at(offset); 664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (*state_values == nullptr || (*state_values)->InputCount() != count) { 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch should_update = true; 666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(static_cast<size_t>(offset + count) <= values()->size()); 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < count; i++) { 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((*state_values)->InputAt(i) != env_values[i]) { 670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch should_update = true; 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (should_update) { 67662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const Operator* op = common()->StateValues(count, SparseInputMask::Dense()); 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (*state_values) = graph()->NewNode(op, count, env_values); 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 682109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochNode* AstGraphBuilder::Environment::Checkpoint(BailoutId ast_id, 683109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch OutputFrameStateCombine combine, 684109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bool owner_has_exception) { 685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!builder()->info()->is_deoptimization_enabled()) { 68613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return builder()->GetEmptyFrameState(); 687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UpdateStateValues(¶meters_node_, 0, parameters_count()); 690c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch UpdateStateValues(&locals_node_, parameters_count(), locals_count()); 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UpdateStateValues(&stack_node_, parameters_count() + locals_count(), 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stack_height()); 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = common()->FrameState( 695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ast_id, combine, builder()->frame_state_function_info()); 696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* result = graph()->NewNode(op, parameters_node_, locals_node_, 698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stack_node_, builder()->current_context(), 699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder()->GetFunctionClosure(), 700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder()->graph()->start()); 701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsLivenessBlockConsistent()); 703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (liveness_block() != nullptr) { 704109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // If the owning node has an exception, register the checkpoint to the 705109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // predecessor so that the checkpoint is used for both the normal and the 706109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // exceptional paths. Yes, this is a terrible hack and we might want 707109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // to use an explicit frame state for the exceptional path. 708109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (owner_has_exception) { 709109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch liveness_block()->GetPredecessor()->Checkpoint(result); 710109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 711109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch liveness_block()->Checkpoint(result); 712109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result; 715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 717f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid AstGraphBuilder::Environment::PrepareForLoopExit( 718f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* loop, BitVector* assigned_variables) { 719f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsMarkedAsUnreachable()) return; 720f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 721f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(loop->opcode(), IrOpcode::kLoop); 722f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 723f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* control = GetControlDependency(); 724f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Create the loop exit node. 726f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* loop_exit = graph()->NewNode(common()->LoopExit(), control, loop); 727f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UpdateControlDependency(loop_exit); 728f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 729f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Rename the environmnent values. 730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (size_t i = 0; i < values()->size(); i++) { 731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (assigned_variables == nullptr || 732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static_cast<int>(i) >= assigned_variables->length() || 733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch assigned_variables->Contains(static_cast<int>(i))) { 734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* rename = graph()->NewNode(common()->LoopExitValue(), (*values())[i], 735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch loop_exit); 736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (*values())[i] = rename; 737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 738f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 739f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 740f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Rename the effect. 741f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* effect_rename = graph()->NewNode(common()->LoopExitEffect(), 742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch GetEffectDependency(), loop_exit); 743f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UpdateEffectDependency(effect_rename); 744f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool AstGraphBuilder::Environment::IsLivenessAnalysisEnabled() { 747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return FLAG_analyze_environment_liveness && 748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder()->info()->is_deoptimization_enabled(); 749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool AstGraphBuilder::Environment::IsLivenessBlockConsistent() { 753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return (!IsLivenessAnalysisEnabled() || IsMarkedAsUnreachable()) == 754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (liveness_block() == nullptr); 755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own, 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression::Context kind) 760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : kind_(kind), owner_(own), outer_(own->ast_context()) { 761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_ast_context(this); // Push. 762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch original_height_ = environment()->stack_height(); 764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstGraphBuilder::AstContext::~AstContext() { 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch owner()->set_ast_context(outer_); // Pop. 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstGraphBuilder::AstEffectContext::~AstEffectContext() { 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(environment()->stack_height() == original_height_); 775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstGraphBuilder::AstValueContext::~AstValueContext() { 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(environment()->stack_height() == original_height_ + 1); 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAstGraphBuilder::AstTestContext::~AstTestContext() { 784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(environment()->stack_height() == original_height_ + 1); 785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 787f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid AstGraphBuilder::AstEffectContext::ProduceValue(Expression* expr, 788f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* value) { 789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The value is ignored. 790f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch owner()->PrepareEagerCheckpoint(expr->id()); 791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 793f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid AstGraphBuilder::AstValueContext::ProduceValue(Expression* expr, 794f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* value) { 795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(value); 796f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch owner()->PrepareEagerCheckpoint(expr->id()); 797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 799f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid AstGraphBuilder::AstTestContext::ProduceValue(Expression* expr, 800f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* value) { 801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Push(owner()->BuildToBoolean(value, feedback_id_)); 802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch owner()->PrepareEagerCheckpoint(expr->id()); 803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::AstEffectContext::ConsumeValue() { return nullptr; } 807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::AstValueContext::ConsumeValue() { 810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return environment()->Pop(); 811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::AstTestContext::ConsumeValue() { 815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return environment()->Pop(); 816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochScope* AstGraphBuilder::current_scope() const { 820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return execution_context_->scope(); 821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::current_context() const { 825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return environment()->Context(); 826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::ControlScope::PerformCommand(Command command, 830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Statement* target, 831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* value) { 832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Environment* env = environment()->CopyAsUnreachable(); 833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ControlScope* current = this; 834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (current != nullptr) { 835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->TrimStack(current->stack_height()); 836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->TrimContextChain(current->context_length()); 837f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (current->Execute(command, target, &value)) break; 838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch current = current->outer_; 839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder()->set_environment(env); 841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NOT_NULL(current); // Always handled (unless stack is malformed). 842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::ControlScope::BreakTo(BreakableStatement* stmt) { 846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PerformCommand(CMD_BREAK, stmt, builder()->jsgraph()->TheHoleConstant()); 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::ControlScope::ContinueTo(BreakableStatement* stmt) { 851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PerformCommand(CMD_CONTINUE, stmt, builder()->jsgraph()->TheHoleConstant()); 852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::ControlScope::ReturnValue(Node* return_value) { 856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PerformCommand(CMD_RETURN, nullptr, return_value); 857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::ControlScope::ThrowValue(Node* exception_value) { 861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PerformCommand(CMD_THROW, nullptr, exception_value); 862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitForValueOrNull(Expression* expr) { 866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (expr == nullptr) { 867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return environment()->Push(jsgraph()->NullConstant()); 868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(expr); 870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::VisitForValueOrTheHole(Expression* expr) { 874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (expr == nullptr) { 875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return environment()->Push(jsgraph()->TheHoleConstant()); 876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitForValue(expr); 878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) { 882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < exprs->length(); ++i) { 883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(exprs->at(i)); 884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitForValue(Expression* expr) { 889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AstValueContext for_value(this); 890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!CheckStackOverflow()) { 891f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitNoStackOverflowCheck(expr); 892958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 893f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant()); 894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitForEffect(Expression* expr) { 899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AstEffectContext for_effect(this); 900958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!CheckStackOverflow()) { 901f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitNoStackOverflowCheck(expr); 902958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 903f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant()); 904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitForTest(Expression* expr) { 909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AstTestContext for_condition(this, expr->test_id()); 910958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!CheckStackOverflow()) { 911f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitNoStackOverflowCheck(expr); 912958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 913f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant()); 914958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 915958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 916958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 917958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 918958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid AstGraphBuilder::Visit(Expression* expr) { 919958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Reuses enclosing AstContext. 920958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!CheckStackOverflow()) { 921f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitNoStackOverflowCheck(expr); 922958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 923f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, jsgraph()->UndefinedConstant()); 924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) { 929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* variable = decl->proxy()->var(); 930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (variable->location()) { 931f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case VariableLocation::UNALLOCATED: { 932bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(!variable->binding_needs_init()); 93362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch globals()->push_back(variable->name()); 93462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FeedbackSlot slot = decl->proxy()->VariableFeedbackSlot(); 935f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(!slot.IsInvalid()); 936f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch globals()->push_back(handle(Smi::FromInt(slot.ToInt()), isolate())); 937bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch globals()->push_back(isolate()->factory()->undefined_value()); 93862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch globals()->push_back(isolate()->factory()->undefined_value()); 939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 940f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::PARAMETER: 942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::LOCAL: 943f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (variable->binding_needs_init()) { 944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = jsgraph()->TheHoleConstant(); 945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Bind(variable, value); 946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::CONTEXT: 949f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (variable->binding_needs_init()) { 950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = jsgraph()->TheHoleConstant(); 951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operator* op = javascript()->StoreContext(0, variable->index()); 95262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch NewNode(op, value); 953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 95562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case VariableLocation::LOOKUP: 956f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case VariableLocation::MODULE: 957f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) { 963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* variable = decl->proxy()->var(); 964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (variable->location()) { 965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::UNALLOCATED: { 966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo( 967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch decl->fun(), info()->script(), info()); 968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check for stack-overflow exception. 969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function.is_null()) return SetStackOverflow(); 97062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch globals()->push_back(variable->name()); 97162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FeedbackSlot slot = decl->proxy()->VariableFeedbackSlot(); 972f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(!slot.IsInvalid()); 973f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch globals()->push_back(handle(Smi::FromInt(slot.ToInt()), isolate())); 97462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 97562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // We need the slot where the literals array lives, too. 97662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch slot = decl->fun()->LiteralFeedbackSlot(); 97762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(!slot.IsInvalid()); 97862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch globals()->push_back(handle(Smi::FromInt(slot.ToInt()), isolate())); 97962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 980958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier globals()->push_back(function); 981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::PARAMETER: 984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::LOCAL: { 985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(decl->fun()); 986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = environment()->Pop(); 987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Bind(variable, value); 988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::CONTEXT: { 991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(decl->fun()); 992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = environment()->Pop(); 993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operator* op = javascript()->StoreContext(0, variable->index()); 99462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch NewNode(op, value); 995bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 996bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 99762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case VariableLocation::LOOKUP: 998f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case VariableLocation::MODULE: 999f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitBlock(Block* stmt) { 1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BlockBuilder block(this); 1006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ControlScopeForBreakable scope(this, stmt, &block); 1007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (stmt->labels() != nullptr) block.BeginBlock(); 1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (stmt->scope() == nullptr) { 1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Visit statements in the same scope, no declarations. 1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitStatements(stmt->statements()); 1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Visit declarations and statements in a block scope. 1013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (stmt->scope()->NeedsContext()) { 1014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* context = BuildLocalBlockContext(stmt->scope()); 1015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ContextScope scope(this, stmt->scope(), context); 1016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitDeclarations(stmt->scope()->declarations()); 1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitStatements(stmt->statements()); 1018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitDeclarations(stmt->scope()->declarations()); 1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitStatements(stmt->statements()); 1021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (stmt->labels() != nullptr) block.EndBlock(); 1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) { 1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForEffect(stmt->expression()); 1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) { 1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Do nothing. 1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::VisitSloppyBlockFunctionStatement( 1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SloppyBlockFunctionStatement* stmt) { 1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Visit(stmt->statement()); 1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitIfStatement(IfStatement* stmt) { 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder compare_if(this); 1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForTest(stmt->condition()); 1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* condition = environment()->Pop(); 1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_if.If(condition); 1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_if.Then(); 1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(stmt->then_statement()); 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_if.Else(); 1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(stmt->else_statement()); 1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_if.End(); 1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) { 1057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch execution_control()->ContinueTo(stmt->target()); 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { 1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch execution_control()->BreakTo(stmt->target()); 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(stmt->expression()); 1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* result = environment()->Pop(); 1069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch execution_control()->ReturnValue(result); 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitWithStatement(WithStatement* stmt) { 107462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Dynamic scoping is supported only by going through Ignition first. 107562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<CaseClause*>* clauses = stmt->cases(); 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SwitchBuilder compare_switch(this, clauses->length()); 1082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ControlScopeForBreakable scope(this, stmt, &compare_switch); 1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_switch.BeginSwitch(); 1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int default_index = -1; 1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Keep the switch value on the stack until a case matches. 1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(stmt->tag()); 1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterate over all cases and create nodes for label comparison. 1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < clauses->length(); i++) { 1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CaseClause* clause = clauses->at(i); 1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The default is not a test, remember index. 1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (clause->is_default()) { 1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default_index = i; 1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continue; 1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create nodes to perform label comparison as if via '==='. The switch 1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // value is still on the operand stack while the label is evaluated. 1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(clause->label()); 1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* label = environment()->Pop(); 1103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* tag = environment()->Top(); 110413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 110562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CompareOperationHint hint = CompareOperationHint::kAny; 1106f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const Operator* op = javascript()->StrictEqual(hint); 1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* condition = NewNode(op, tag, label); 1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_switch.BeginLabel(i, condition); 1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Discard the switch value at label match. 1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Pop(); 1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_switch.EndLabel(); 1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Discard the switch value and mark the default case. 1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Pop(); 1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (default_index >= 0) { 1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_switch.DefaultAt(default_index); 1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterate over all cases and create nodes for case bodies. 1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < clauses->length(); i++) { 1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CaseClause* clause = clauses->at(i); 1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_switch.BeginCase(i); 1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitStatements(clause->statements()); 1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_switch.EndCase(); 1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_switch.EndSwitch(); 1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { 1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder while_loop(this); 1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); 1136f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitIterationBody(stmt, &while_loop, stmt->StackCheckId()); 1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while_loop.EndBody(); 1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForTest(stmt->cond()); 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* condition = environment()->Pop(); 1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while_loop.BreakUnless(condition); 1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while_loop.EndLoop(); 1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { 1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder while_loop(this); 1147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); 1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForTest(stmt->cond()); 1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* condition = environment()->Pop(); 1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while_loop.BreakUnless(condition); 1151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitIterationBody(stmt, &while_loop, stmt->StackCheckId()); 1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while_loop.EndBody(); 1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while_loop.EndLoop(); 1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitForStatement(ForStatement* stmt) { 1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoopBuilder for_loop(this); 1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitIfNotNull(stmt->init()); 1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); 1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (stmt->cond() != nullptr) { 1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForTest(stmt->cond()); 1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* condition = environment()->Pop(); 1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for_loop.BreakUnless(condition); 1165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for_loop.BreakUnless(jsgraph()->TrueConstant()); 1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitIterationBody(stmt, &for_loop, stmt->StackCheckId()); 1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for_loop.EndBody(); 1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitIfNotNull(stmt->next()); 1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for_loop.EndLoop(); 1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) { 117662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Only the BytecodeGraphBuilder supports for-in. 117762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return SetStackOverflow(); 1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) { 118262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Iterator looping is supported only by going through Ignition first. 118362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { 118862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Exception handling is supported only by going through Ignition first. 118962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 119462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Exception handling is supported only by going through Ignition first. 119562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { 120062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Debugger statement is supported only by going through Ignition first. 120162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { 1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Find or build a shared function info. 1207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SharedFunctionInfo> shared_info = 1208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Compiler::GetSharedFunctionInfo(expr, info()->script(), info()); 1209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(!shared_info.is_null()); // TODO(mstarzinger): Set stack overflow? 1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create node to instantiate a new closure. 1212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PretenureFlag pretenure = expr->pretenure() ? TENURED : NOT_TENURED; 121362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch VectorSlotPair pair = CreateVectorSlotPair(expr->LiteralFeedbackSlot()); 121462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const Operator* op = 121562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch javascript()->CreateClosure(shared_info, pair, pretenure); 1216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* value = NewNode(op); 1217f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 122062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { UNREACHABLE(); } 1221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { 1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::VisitDoExpression(DoExpression* expr) { 1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitBlock(expr->block()); 1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitVariableProxy(expr->result()); 1230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ReplaceValue(expr); 1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::VisitConditional(Conditional* expr) { 1235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IfBuilder compare_if(this); 1236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitForTest(expr->condition()); 1237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* condition = environment()->Pop(); 1238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch compare_if.If(condition); 1239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch compare_if.Then(); 1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(expr->then_expression()); 1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_if.Else(); 1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(expr->else_expression()); 1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_if.End(); 1244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Skip plugging AST evaluation contexts of the test kind. This is to stay in 1245f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // sync with full codegen which doesn't prepare the proper bailout point (see 1246f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // the implementation of FullCodeGenerator::VisitForControl). 1247f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (ast_context()->IsTest()) return; 1248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ReplaceValue(expr); 1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 1253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot()); 125413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareEagerCheckpoint(BeforeId(expr)); 125513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* value = BuildVariableLoad(expr->var(), expr->id(), pair, 1256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ast_context()->GetStateCombine()); 1257f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitLiteral(Literal* expr) { 1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = jsgraph()->Constant(expr->value()); 1263f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* closure = GetFunctionClosure(); 1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create node to materialize a regular expression literal. 1271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = javascript()->CreateLiteralRegExp( 127262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch expr->pattern(), expr->flags(), 127362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FeedbackVector::GetIndex(expr->literal_slot())); 1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* literal = NewNode(op, closure); 1275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrepareFrameState(literal, expr->id(), ast_context()->GetStateCombine()); 1276f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, literal); 1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { 1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* closure = GetFunctionClosure(); 1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create node to deep-copy the literal boilerplate. 1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = javascript()->CreateLiteralObject( 128562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch expr->GetOrBuildConstantProperties(isolate()), expr->ComputeFlags(true), 128662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FeedbackVector::GetIndex(expr->literal_slot()), expr->properties_count()); 1287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* literal = NewNode(op, closure); 1288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrepareFrameState(literal, expr->CreateLiteralId(), 1289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OutputFrameStateCombine::Push()); 1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The object is expected on the operand stack during computation of the 1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // property values and is the value of the entire expression. 1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(literal); 1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create nodes to store computed values into the literal. 1296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AccessorTable accessor_table(local_zone()); 129762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (int i = 0; i < expr->properties()->length(); i++) { 129862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ObjectLiteral::Property* property = expr->properties()->at(i); 129962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(!property->is_computed_name()); 1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (property->IsCompileTimeValue()) continue; 1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Literal* key = property->key()->AsLiteral(); 1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (property->kind()) { 130462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case ObjectLiteral::Property::SPREAD: 1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ObjectLiteral::Property::CONSTANT: 1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); 1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fall through. 1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ObjectLiteral::Property::COMPUTED: { 1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // It is safe to use [[Put]] here because the boilerplate already 1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // contains computed properties with an uninitialized value. 1313f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (key->IsStringLiteral()) { 1314f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(key->IsPropertyName()); 1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (property->emit_store()) { 1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(property->value()); 1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = environment()->Pop(); 1318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* literal = environment()->Top(); 1319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> name = key->AsPropertyName(); 1320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VectorSlotPair feedback = 1321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CreateVectorSlotPair(property->GetSlot(0)); 132262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* store = BuildNamedStoreOwn(literal, name, value, feedback); 132313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareFrameState(store, key->id(), 132413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch OutputFrameStateCombine::Ignore()); 1325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildSetHomeObject(value, literal, property, 1); 1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForEffect(property->value()); 1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Push(environment()->Top()); // Duplicate receiver. 1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(property->key()); 1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(property->value()); 1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = environment()->Pop(); 1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* key = environment()->Pop(); 1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* receiver = environment()->Pop(); 1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (property->emit_store()) { 1338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* language = jsgraph()->Constant(SLOPPY); 1339109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const Operator* op = javascript()->CallRuntime(Runtime::kSetProperty); 1340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* set_property = NewNode(op, receiver, key, value, language); 1341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // SetProperty should not lazy deopt on an object literal. 1342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrepareFrameState(set_property, BailoutId::None()); 1343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildSetHomeObject(value, receiver, property); 1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ObjectLiteral::Property::PROTOTYPE: { 1348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Push(environment()->Top()); // Duplicate receiver. 1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(property->value()); 1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = environment()->Pop(); 1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* receiver = environment()->Pop(); 1352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(property->emit_store()); 1353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = 1354109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch javascript()->CallRuntime(Runtime::kInternalSetPrototype); 1355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* set_prototype = NewNode(op, receiver, value); 1356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // SetPrototype should not lazy deopt on an object literal. 135762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PrepareFrameState(set_prototype, expr->GetIdForPropertySet(i)); 1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ObjectLiteral::Property::GETTER: 1361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (property->emit_store()) { 136213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch AccessorTable::Iterator it = accessor_table.lookup(key); 136362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch it->second->bailout_id = expr->GetIdForPropertySet(i); 136413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch it->second->getter = property; 1365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ObjectLiteral::Property::SETTER: 1368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (property->emit_store()) { 136913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch AccessorTable::Iterator it = accessor_table.lookup(key); 137062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch it->second->bailout_id = expr->GetIdForPropertySet(i); 137113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch it->second->setter = property; 1372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create nodes to define accessors, using only a single call to the runtime 1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for each pair of corresponding getters and setters. 1379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch literal = environment()->Top(); // Reload from operand stack. 1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (AccessorTable::Iterator it = accessor_table.begin(); 1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch it != accessor_table.end(); ++it) { 1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(it->first); 1383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitObjectLiteralAccessor(literal, it->second->getter); 1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitObjectLiteralAccessor(literal, it->second->setter); 1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* setter = environment()->Pop(); 1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* getter = environment()->Pop(); 1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* name = environment()->Pop(); 1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* attr = jsgraph()->Constant(NONE); 1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operator* op = 1390109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked); 1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* call = NewNode(op, literal, name, getter, setter, attr); 139213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareFrameState(call, it->second->bailout_id); 1393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1394f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, environment()->Pop()); 1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::VisitObjectLiteralAccessor( 1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* home_object, ObjectLiteralProperty* property) { 1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (property == nullptr) { 1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitForValueOrNull(nullptr); 1402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitForValue(property->value()); 1404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildSetHomeObject(environment()->Top(), home_object, property); 1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { 1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* closure = GetFunctionClosure(); 1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create node to deep-copy the literal boilerplate. 1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = javascript()->CreateLiteralArray( 141462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch expr->GetOrBuildConstantElements(isolate()), expr->ComputeFlags(true), 141562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FeedbackVector::GetIndex(expr->literal_slot()), expr->values()->length()); 1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* literal = NewNode(op, closure); 1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrepareFrameState(literal, expr->CreateLiteralId(), 1418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutputFrameStateCombine::Push()); 1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The array is expected on the operand stack during computation of the 1421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // element values. 1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(literal); 1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create nodes to evaluate all the non-constant subexpressions and to store 1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // them into the newly cloned array. 1426f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch for (int array_index = 0; array_index < expr->values()->length(); 1427f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch array_index++) { 1428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Expression* subexpr = expr->values()->at(array_index); 1429109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(!subexpr->IsSpread()); 1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(subexpr); 1433f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VectorSlotPair pair = CreateVectorSlotPair(expr->LiteralFeedbackSlot()); 1434f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* value = environment()->Pop(); 1435f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* index = jsgraph()->Constant(array_index); 1436f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* literal = environment()->Top(); 1437f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* store = BuildKeyedStore(literal, index, value, pair); 1438f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PrepareFrameState(store, expr->GetIdForElement(array_index), 1439f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch OutputFrameStateCombine::Ignore()); 1440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1442f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, environment()->Pop()); 1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitAssignment(Assignment* expr) { 1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); 1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Left-hand side can only be a property, a global or a variable slot. 1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Property* property = expr->target()->AsProperty(); 1450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LhsKind assign_type = Property::GetAssignType(property); 1451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool needs_frame_state_before = true; 1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Evaluate LHS expression. 1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (assign_type) { 1455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VARIABLE: { 1456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Variable* variable = expr->target()->AsVariableProxy()->var(); 1457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (variable->location() == VariableLocation::PARAMETER || 1458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch variable->location() == VariableLocation::LOCAL || 1459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch variable->location() == VariableLocation::CONTEXT) { 1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch needs_frame_state_before = false; 1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case NAMED_PROPERTY: 1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(property->obj()); 1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case KEYED_PROPERTY: 1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(property->obj()); 1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(property->key()); 1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case NAMED_SUPER_PROPERTY: 1472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case KEYED_SUPER_PROPERTY: 147362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 1474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Evaluate the value and potentially handle compound assignments by loading 1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the left-hand side value and performing a binary operation. 1479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->is_compound()) { 1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* old_value = nullptr; 1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (assign_type) { 1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case VARIABLE: { 1483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VariableProxy* proxy = expr->target()->AsVariableProxy(); 1484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VectorSlotPair pair = 1485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CreateVectorSlotPair(proxy->VariableFeedbackSlot()); 148613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareEagerCheckpoint(BeforeId(proxy)); 148713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair, 148813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch OutputFrameStateCombine::Push()); 1489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case NAMED_PROPERTY: { 1492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* object = environment()->Top(); 1493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); 1494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VectorSlotPair pair = 1495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CreateVectorSlotPair(property->PropertyFeedbackSlot()); 1496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch old_value = BuildNamedLoad(object, name, pair); 149713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareFrameState(old_value, property->LoadId(), 149813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch OutputFrameStateCombine::Push()); 1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case KEYED_PROPERTY: { 1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* key = environment()->Top(); 1503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* object = environment()->Peek(1); 1504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VectorSlotPair pair = 1505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CreateVectorSlotPair(property->PropertyFeedbackSlot()); 1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch old_value = BuildKeyedLoad(object, key, pair); 150713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareFrameState(old_value, property->LoadId(), 150813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch OutputFrameStateCombine::Push()); 1509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 151162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case NAMED_SUPER_PROPERTY: 151262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case KEYED_SUPER_PROPERTY: 151362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(old_value); 1517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(expr->value()); 1518f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* right = environment()->Pop(); 1519f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* left = environment()->Pop(); 1520f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* value = 1521f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BuildBinaryOp(left, right, expr->binary_op(), 1522f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch expr->binary_operation()->BinaryOperationFeedbackId()); 1523f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PrepareFrameState(value, expr->binary_operation()->id(), 1524f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch OutputFrameStateCombine::Push()); 1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(value); 1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (needs_frame_state_before) { 1527f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PrepareEagerCheckpoint(expr->binary_operation()->id()); 1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(expr->value()); 1531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Store the value. 1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = environment()->Pop(); 1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VectorSlotPair feedback = CreateVectorSlotPair(expr->AssignmentSlot()); 1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (assign_type) { 1537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case VARIABLE: { 1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* variable = expr->target()->AsVariableProxy()->var(); 1539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildVariableAssignment(variable, value, expr->op(), feedback, expr->id(), 154013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ast_context()->GetStateCombine()); 1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case NAMED_PROPERTY: { 1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* object = environment()->Pop(); 1545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); 1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* store = BuildNamedStore(object, name, value, feedback); 1547f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PrepareFrameState(store, expr->AssignmentId(), 1548f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch OutputFrameStateCombine::Push()); 1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case KEYED_PROPERTY: { 1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* key = environment()->Pop(); 1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* object = environment()->Pop(); 1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* store = BuildKeyedStore(object, key, value, feedback); 1555f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PrepareFrameState(store, expr->AssignmentId(), 1556f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch OutputFrameStateCombine::Push()); 1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 155962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case NAMED_SUPER_PROPERTY: 156062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case KEYED_SUPER_PROPERTY: 156162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1565f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 1566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitYield(Yield* expr) { 1570bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Generator functions are supported only by going through Ignition first. 157162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitThrow(Throw* expr) { 1576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(expr->exception()); 1577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* exception = environment()->Pop(); 1578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* value = BuildThrowError(exception, expr->id()); 1579f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitProperty(Property* expr) { 1584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* value = nullptr; 1585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LhsKind property_kind = Property::GetAssignType(expr); 1586958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot()); 1587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (property_kind) { 1588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VARIABLE: 1589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case NAMED_PROPERTY: { 1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitForValue(expr->obj()); 1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* object = environment()->Pop(); 1594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName(); 1595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value = BuildNamedLoad(object, name, pair); 1596f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PrepareFrameState(value, expr->LoadId(), OutputFrameStateCombine::Push()); 1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case KEYED_PROPERTY: { 1600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitForValue(expr->obj()); 1601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitForValue(expr->key()); 1602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* key = environment()->Pop(); 1603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* object = environment()->Pop(); 1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value = BuildKeyedLoad(object, key, pair); 1605f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PrepareFrameState(value, expr->LoadId(), OutputFrameStateCombine::Push()); 1606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 160862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case NAMED_SUPER_PROPERTY: 160962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case KEYED_SUPER_PROPERTY: 161062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 1611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1613f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitCall(Call* expr) { 1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* callee = expr->expression(); 1619f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Call::CallType call_type = expr->GetCallType(); 162062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CHECK(!expr->is_possibly_eval()); 1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Prepare the callee and the receiver to the function call. This depends on 1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the semantics of the underlying call type. 1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; 1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* receiver_value = nullptr; 1626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* callee_value = nullptr; 162762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch switch (call_type) { 162862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Call::GLOBAL_CALL: { 162962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch VariableProxy* proxy = callee->AsVariableProxy(); 163062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); 163162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PrepareEagerCheckpoint(BeforeId(proxy)); 163262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch callee_value = BuildVariableLoad(proxy->var(), expr->expression()->id(), 163362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch pair, OutputFrameStateCombine::Push()); 1634c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch receiver_hint = ConvertReceiverMode::kNullOrUndefined; 1635c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch receiver_value = jsgraph()->UndefinedConstant(); 163662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch break; 1637958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 163862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Call::NAMED_PROPERTY_CALL: { 163962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Property* property = callee->AsProperty(); 164062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch VectorSlotPair feedback = 164162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CreateVectorSlotPair(property->PropertyFeedbackSlot()); 164262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch VisitForValue(property->obj()); 164362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); 164462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* object = environment()->Top(); 164562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch callee_value = BuildNamedLoad(object, name, feedback); 164662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PrepareFrameState(callee_value, property->LoadId(), 164762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch OutputFrameStateCombine::Push()); 164862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Note that a property call requires the receiver to be wrapped into 164962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // an object for sloppy callees. However the receiver is guaranteed 165062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // not to be null or undefined at this point. 165162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch receiver_hint = ConvertReceiverMode::kNotNullOrUndefined; 165262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch receiver_value = environment()->Pop(); 165362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch break; 165462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 165562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Call::KEYED_PROPERTY_CALL: { 165662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Property* property = callee->AsProperty(); 165762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch VectorSlotPair feedback = 165862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CreateVectorSlotPair(property->PropertyFeedbackSlot()); 165962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch VisitForValue(property->obj()); 166062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch VisitForValue(property->key()); 166162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* key = environment()->Pop(); 166262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* object = environment()->Top(); 166362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch callee_value = BuildKeyedLoad(object, key, feedback); 166462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PrepareFrameState(callee_value, property->LoadId(), 166562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch OutputFrameStateCombine::Push()); 166662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Note that a property call requires the receiver to be wrapped into 166762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // an object for sloppy callees. However the receiver is guaranteed 166862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // not to be null or undefined at this point. 166962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch receiver_hint = ConvertReceiverMode::kNotNullOrUndefined; 167062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch receiver_value = environment()->Pop(); 167162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch break; 1672c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 167362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Call::OTHER_CALL: 167462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch VisitForValue(callee); 167562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch callee_value = environment()->Pop(); 167662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch receiver_hint = ConvertReceiverMode::kNullOrUndefined; 167762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch receiver_value = jsgraph()->UndefinedConstant(); 167862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch break; 167962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Call::NAMED_SUPER_PROPERTY_CALL: 168062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Call::KEYED_SUPER_PROPERTY_CALL: 168162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Call::SUPER_CALL: 168262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Call::WITH_CALL: 168362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The callee and the receiver both have to be pushed onto the operand stack 1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // before arguments are being evaluated. 1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(callee_value); 1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(receiver_value); 1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Evaluate all arguments to the function call, 1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Expression*>* args = expr->arguments(); 1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValues(args); 1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create node to perform the function call. 1696f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch float const frequency = ComputeCallFrequency(expr->CallFeedbackICSlot()); 1697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot()); 1698f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const Operator* call = 169962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch javascript()->Call(args->length() + 2, frequency, feedback, receiver_hint, 170062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch expr->tail_call_mode()); 170162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PrepareEagerCheckpoint(expr->CallId()); 1702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* value = ProcessArguments(call, args->length() + 2); 1703f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // The callee passed to the call, we just need to push something here to 1704f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // satisfy the bailout location contract. The fullcodegen code will not 1705f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // ever look at this value, so we just push optimized_out here. 1706f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch environment()->Push(jsgraph()->OptimizedOutConstant()); 170713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); 1708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Drop(1); 1709f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 1710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitCallNew(CallNew* expr) { 1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(expr->expression()); 1715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Evaluate all arguments to the construct call. 1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Expression*>* args = expr->arguments(); 1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValues(args); 1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The new target is the same as the callee. 1721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Push(environment()->Peek(args->length())); 1722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create node to perform the construct call. 1724f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch float const frequency = ComputeCallFrequency(expr->CallNewFeedbackSlot()); 1725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VectorSlotPair feedback = CreateVectorSlotPair(expr->CallNewFeedbackSlot()); 1726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* call = 172762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch javascript()->Construct(args->length() + 2, frequency, feedback); 1728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* value = ProcessArguments(call, args->length() + 2); 172913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); 1730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 1731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { 1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The callee and the receiver both have to be pushed onto the operand stack 1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // before arguments are being evaluated. 1737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* callee_value = BuildLoadNativeContextField(expr->context_index()); 1738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* receiver_value = jsgraph()->UndefinedConstant(); 1739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(callee_value); 1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(receiver_value); 1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Evaluate all arguments to the JS runtime call. 1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Expression*>* args = expr->arguments(); 1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValues(args); 1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create node to perform the JS runtime call. 174862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const Operator* call = javascript()->Call(args->length() + 2); 174913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareEagerCheckpoint(expr->CallId()); 1750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = ProcessArguments(call, args->length() + 2); 175113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); 1752f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { 1757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle calls to runtime functions implemented in JavaScript separately as 1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the call follows JavaScript ABI and the callee is statically unknown. 1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->is_jsruntime()) { 1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return VisitCallJSRuntime(expr); 1761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Evaluate all arguments to the runtime call. 1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Expression*>* args = expr->arguments(); 1765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValues(args); 1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create node to perform the runtime call. 17683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Runtime::FunctionId functionId = expr->function()->function_id; 1769958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const Operator* call = javascript()->CallRuntime(functionId, args->length()); 1770f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (expr->function()->intrinsic_type == Runtime::IntrinsicType::RUNTIME || 1771f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch expr->function()->function_id == Runtime::kInlineCall) { 1772f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PrepareEagerCheckpoint(expr->CallId()); 1773f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = ProcessArguments(call, args->length()); 177513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); 1776f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { 1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (expr->op()) { 1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::DELETE: 1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return VisitDelete(expr); 1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::VOID: 1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return VisitVoid(expr); 1786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::TYPEOF: 1787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return VisitTypeof(expr); 1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::NOT: 1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return VisitNot(expr); 1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitCountOperation(CountOperation* expr) { 1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); 1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Left-hand side can only be a property, a global or a variable slot. 1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Property* property = expr->expression()->AsProperty(); 1801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LhsKind assign_type = Property::GetAssignType(property); 1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Reserve space for result of postfix operation. 1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_postfix = expr->is_postfix() && !ast_context()->IsEffect(); 1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_postfix && assign_type != VARIABLE) { 1806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Push(jsgraph()->ZeroConstant()); 1807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Evaluate LHS expression and get old value. 1810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* old_value = nullptr; 1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int stack_depth = -1; 1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (assign_type) { 1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case VARIABLE: { 1814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VariableProxy* proxy = expr->expression()->AsVariableProxy(); 1815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); 181613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareEagerCheckpoint(BeforeId(proxy)); 181713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch old_value = BuildVariableLoad(proxy->var(), expr->expression()->id(), 181813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch pair, OutputFrameStateCombine::Push()); 1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stack_depth = 0; 1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case NAMED_PROPERTY: { 1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(property->obj()); 1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* object = environment()->Top(); 1825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); 1826958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VectorSlotPair pair = 1827958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CreateVectorSlotPair(property->PropertyFeedbackSlot()); 1828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch old_value = BuildNamedLoad(object, name, pair); 182913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareFrameState(old_value, property->LoadId(), 183013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch OutputFrameStateCombine::Push()); 1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stack_depth = 1; 1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case KEYED_PROPERTY: { 1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(property->obj()); 1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(property->key()); 1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* key = environment()->Top(); 1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* object = environment()->Peek(1); 1839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VectorSlotPair pair = 1840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CreateVectorSlotPair(property->PropertyFeedbackSlot()); 1841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch old_value = BuildKeyedLoad(object, key, pair); 184213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareFrameState(old_value, property->LoadId(), 184313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch OutputFrameStateCombine::Push()); 1844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stack_depth = 2; 1845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 184762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case NAMED_SUPER_PROPERTY: 184862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case KEYED_SUPER_PROPERTY: 184962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 1850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convert old value into a number. 18543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch old_value = NewNode(javascript()->ToNumber(), old_value); 18553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch PrepareFrameState(old_value, expr->ToNumberId(), 18563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch OutputFrameStateCombine::Push()); 1857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Create a proper eager frame state for the stores. 1859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Push(old_value); 1860f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PrepareEagerCheckpoint(expr->ToNumberId()); 1861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch old_value = environment()->Pop(); 1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Save result for postfix expressions at correct stack depth. 1864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_postfix) { 1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (assign_type != VARIABLE) { 1866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Poke(stack_depth, old_value); 1867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Push(old_value); 1869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create node to perform +1/-1 operation. 187313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* value = BuildBinaryOp(old_value, jsgraph()->OneConstant(), 187413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch expr->binary_op(), expr->CountBinOpFeedbackId()); 1875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // This should never lazy deopt because we have converted to number before. 1876f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PrepareFrameState(value, BailoutId::None()); 1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Store the value. 1879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VectorSlotPair feedback = CreateVectorSlotPair(expr->CountSlot()); 1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (assign_type) { 1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case VARIABLE: { 1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Variable* variable = expr->expression()->AsVariableProxy()->var(); 1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(value); 1884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildVariableAssignment(variable, value, expr->op(), feedback, 188513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch expr->AssignmentId()); 1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Pop(); 1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case NAMED_PROPERTY: { 1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* object = environment()->Pop(); 1891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); 1892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* store = BuildNamedStore(object, name, value, feedback); 189313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareFrameState(store, expr->AssignmentId(), 1894f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch OutputFrameStateCombine::Push()); 1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case KEYED_PROPERTY: { 1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* key = environment()->Pop(); 1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* object = environment()->Pop(); 1900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* store = BuildKeyedStore(object, key, value, feedback); 190113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareFrameState(store, expr->AssignmentId(), 1902f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch OutputFrameStateCombine::Push()); 1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 190562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case NAMED_SUPER_PROPERTY: 190662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case KEYED_SUPER_PROPERTY: 190762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Restore old value for postfix expressions. 1912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_postfix) value = environment()->Pop(); 1913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1914f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 1915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { 1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (expr->op()) { 1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::COMMA: 1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return VisitComma(expr); 1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::OR: 1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::AND: 1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return VisitLogicalExpression(expr); 1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: { 1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(expr->left()); 1927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(expr->right()); 1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* right = environment()->Pop(); 1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* left = environment()->Pop(); 1930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* value = BuildBinaryOp(left, right, expr->op(), 1931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch expr->BinaryOperationFeedbackId()); 1932f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); 1933f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 19383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid AstGraphBuilder::VisitLiteralCompareNil(CompareOperation* expr, 19393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Expression* sub_expr, 19403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* nil_value) { 19413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch const Operator* op = nullptr; 19423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch switch (expr->op()) { 19433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case Token::EQ: 1944f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch op = javascript()->Equal(CompareOperationHint::kAny); 19453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 19463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case Token::EQ_STRICT: 1947f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch op = javascript()->StrictEqual(CompareOperationHint::kAny); 19483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 19493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch default: 19503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch UNREACHABLE(); 19513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 19523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch VisitForValue(sub_expr); 19533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* value_to_compare = environment()->Pop(); 19543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* value = NewNode(op, value_to_compare, nil_value); 195513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); 1956f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return ast_context()->ProduceValue(expr, value); 19573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 19583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 19593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid AstGraphBuilder::VisitLiteralCompareTypeof(CompareOperation* expr, 19603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Expression* sub_expr, 19613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<String> check) { 19623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch VisitTypeofExpression(sub_expr); 19633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* typeof_arg = NewNode(javascript()->TypeOf(), environment()->Pop()); 1964f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* value = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), 196513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch typeof_arg, jsgraph()->Constant(check)); 196613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); 1967f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return ast_context()->ProduceValue(expr, value); 19683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 19713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Check for a few fast cases. The AST visiting behavior must be in sync 19723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // with the full codegen: We don't push both left and right values onto 19733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // the expression stack when one side is a special-case literal. 19743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Expression* sub_expr = nullptr; 19753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<String> check; 19763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { 19773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitLiteralCompareTypeof(expr, sub_expr, check); 19783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 19793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (expr->IsLiteralCompareUndefined(&sub_expr)) { 19803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitLiteralCompareNil(expr, sub_expr, 19813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch jsgraph()->UndefinedConstant()); 19823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 19833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (expr->IsLiteralCompareNull(&sub_expr)) { 19843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitLiteralCompareNil(expr, sub_expr, jsgraph()->NullConstant()); 19853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 19863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 198762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CompareOperationHint hint = CompareOperationHint::kAny; 1988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operator* op; 1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (expr->op()) { 1990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::EQ: 1991f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch op = javascript()->Equal(hint); 1992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::NE: 1994f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch op = javascript()->NotEqual(hint); 1995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::EQ_STRICT: 1997f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch op = javascript()->StrictEqual(hint); 1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::NE_STRICT: 2000f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch op = javascript()->StrictNotEqual(hint); 2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::LT: 2003f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch op = javascript()->LessThan(hint); 2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::GT: 2006f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch op = javascript()->GreaterThan(hint); 2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::LTE: 2009f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch op = javascript()->LessThanOrEqual(hint); 2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::GTE: 2012f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch op = javascript()->GreaterThanOrEqual(hint); 2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::INSTANCEOF: 2015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch op = javascript()->InstanceOf(); 2016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::IN: 2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch op = javascript()->HasProperty(); 2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 2021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch op = nullptr; 2022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 2023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(expr->left()); 2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(expr->right()); 2026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* right = environment()->Pop(); 2027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* left = environment()->Pop(); 2028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = NewNode(op, left, right); 2029f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); 2030f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 2031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::VisitSpread(Spread* expr) { 2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Handled entirely by the parser itself. 2036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 2037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::VisitEmptyParentheses(EmptyParentheses* expr) { 2041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Handled entirely by the parser itself. 2042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 2043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 204562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid AstGraphBuilder::VisitGetIterator(GetIterator* expr) { 204662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // GetIterator is supported only by going through Ignition first. 204762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 204862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 2049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitThisFunction(ThisFunction* expr) { 2051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = GetFunctionClosure(); 2052f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::VisitSuperPropertyReference( 2057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SuperPropertyReference* expr) { 205862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 2059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::VisitSuperCallReference(SuperCallReference* expr) { 2063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Handled by VisitCall 2064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::VisitCaseClause(CaseClause* expr) { 2069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Handled entirely in VisitSwitch. 2070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 2071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2073c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid AstGraphBuilder::VisitDeclarations(Declaration::List* declarations) { 2074958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(globals()->empty()); 2075f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AstVisitor<AstGraphBuilder>::VisitDeclarations(declarations); 2076958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (globals()->empty()) return; 2077958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int array_index = 0; 207862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FeedbackVector> feedback_vector(info()->closure()->feedback_vector()); 2079958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<FixedArray> data = isolate()->factory()->NewFixedArray( 2080958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<int>(globals()->size()), TENURED); 2081958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (Handle<Object> obj : *globals()) data->set(array_index++, *obj); 2082bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch int encoded_flags = info()->GetDeclareGlobalsFlags(); 2083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* flags = jsgraph()->Constant(encoded_flags); 208462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* decls = jsgraph()->Constant(data); 2085f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* vector = jsgraph()->Constant(feedback_vector); 2086109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const Operator* op = javascript()->CallRuntime(Runtime::kDeclareGlobals); 208762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* call = NewNode(op, decls, flags, vector); 2088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrepareFrameState(call, BailoutId::Declarations()); 2089958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier globals()->clear(); 2090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitIfNotNull(Statement* stmt) { 2094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (stmt == nullptr) return; 2095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Visit(stmt); 2096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitIterationBody(IterationStatement* stmt, 2100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LoopBuilder* loop, 2101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BailoutId stack_check_id) { 2102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ControlScopeForIteration scope(this, stmt, loop); 210362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* node = NewNode(javascript()->StackCheck()); 210462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PrepareFrameState(node, stack_check_id); 2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(stmt->body()); 2106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitDelete(UnaryOperation* expr) { 2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value; 2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->expression()->IsVariableProxy()) { 2112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Delete of an unqualified identifier is disallowed in strict mode but 2113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // "delete this" is allowed. 2114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Variable* variable = expr->expression()->AsVariableProxy()->var(); 2115f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(is_sloppy(language_mode()) || variable->is_this()); 2116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value = BuildVariableDelete(variable, expr->id(), 2117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ast_context()->GetStateCombine()); 2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (expr->expression()->IsProperty()) { 2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Property* property = expr->expression()->AsProperty(); 2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(property->obj()); 2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForValue(property->key()); 2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* key = environment()->Pop(); 2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* object = environment()->Pop(); 2124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value = NewNode(javascript()->DeleteProperty(language_mode()), object, key); 2125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); 2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForEffect(expr->expression()); 2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value = jsgraph()->TrueConstant(); 2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2130f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitVoid(UnaryOperation* expr) { 2135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForEffect(expr->expression()); 2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = jsgraph()->UndefinedConstant(); 2137f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 21403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid AstGraphBuilder::VisitTypeofExpression(Expression* expr) { 21413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (expr->IsVariableProxy()) { 2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Typeof does not throw a reference error on global variables, hence we 2143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // perform a non-contextual load in case the operand is a variable proxy. 21443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch VariableProxy* proxy = expr->AsVariableProxy(); 2145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot()); 214613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareEagerCheckpoint(BeforeId(proxy)); 21473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* load = 214813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch BuildVariableLoad(proxy->var(), expr->id(), pair, 2149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutputFrameStateCombine::Push(), INSIDE_TYPEOF); 21503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch environment()->Push(load); 2151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 21523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch VisitForValue(expr); 2153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 21543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 21553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 21563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid AstGraphBuilder::VisitTypeof(UnaryOperation* expr) { 21573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch VisitTypeofExpression(expr->expression()); 21583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* value = NewNode(javascript()->TypeOf(), environment()->Pop()); 2159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 2160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitNot(UnaryOperation* expr) { 2164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitForTest(expr->expression()); 2165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* input = environment()->Pop(); 2166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* value = NewNode(common()->Select(MachineRepresentation::kTagged), input, 2167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->FalseConstant(), jsgraph()->TrueConstant()); 2168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Skip plugging AST evaluation contexts of the test kind. This is to stay in 2169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // sync with full codegen which doesn't prepare the proper bailout point (see 2170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // the implementation of FullCodeGenerator::VisitForControl). 2171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (ast_context()->IsTest()) return environment()->Push(value); 2172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ProduceValue(expr, value); 2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitComma(BinaryOperation* expr) { 2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForEffect(expr->left()); 2178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(expr->right()); 2179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Skip plugging AST evaluation contexts of the test kind. This is to stay in 2180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // sync with full codegen which doesn't prepare the proper bailout point (see 2181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // the implementation of FullCodeGenerator::VisitForControl). 2182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (ast_context()->IsTest()) return; 2183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ReplaceValue(expr); 2184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) { 2188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_logical_and = expr->op() == Token::AND; 2189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder compare_if(this); 2190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Only use an AST evaluation context of the value kind when this expression 2191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // is evaluated as value as well. Otherwise stick to a test context which is 2192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // in sync with full codegen (see FullCodeGenerator::VisitLogicalExpression). 2193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* condition = nullptr; 2194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (ast_context()->IsValue()) { 2195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitForValue(expr->left()); 2196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* left = environment()->Top(); 2197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch condition = BuildToBoolean(left, expr->left()->test_id()); 2198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitForTest(expr->left()); 2200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch condition = environment()->Top(); 2201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch compare_if.If(condition); 2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_if.Then(); 2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_logical_and) { 2205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Pop(); 2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(expr->right()); 2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (ast_context()->IsEffect()) { 2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Pop(); 2209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (ast_context()->IsTest()) { 2210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Poke(0, jsgraph()->TrueConstant()); 2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_if.Else(); 2213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!is_logical_and) { 2214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Pop(); 2215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(expr->right()); 2216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (ast_context()->IsEffect()) { 2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Pop(); 2218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (ast_context()->IsTest()) { 2219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Poke(0, jsgraph()->FalseConstant()); 2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compare_if.End(); 2222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Skip plugging AST evaluation contexts of the test kind. This is to stay in 2223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // sync with full codegen which doesn't prepare the proper bailout point (see 2224f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // the implementation of FullCodeGenerator::VisitForControl). 2225f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (ast_context()->IsTest()) return; 2226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ast_context()->ReplaceValue(expr); 2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLanguageMode AstGraphBuilder::language_mode() const { 22313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return current_scope()->language_mode(); 2232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 223462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochVectorSlotPair AstGraphBuilder::CreateVectorSlotPair(FeedbackSlot slot) const { 223513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return VectorSlotPair(handle(info()->closure()->feedback_vector()), slot); 2236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2239109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid AstGraphBuilder::VisitRewritableExpression(RewritableExpression* node) { 2240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Visit(node->expression()); 2241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 224362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochfloat AstGraphBuilder::ComputeCallFrequency(FeedbackSlot slot) const { 2244f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (slot.IsInvalid()) return 0.0f; 224562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FeedbackVector> feedback_vector(info()->closure()->feedback_vector(), 224662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate()); 2247f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch CallICNexus nexus(feedback_vector, slot); 2248f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return nexus.ComputeCallFrequency() * invocation_frequency_; 2249f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 2250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) { 2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(environment()->stack_height() >= arity); 2253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node** all = info()->zone()->NewArray<Node*>(arity); 2254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = arity - 1; i >= 0; --i) { 2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch all[i] = environment()->Pop(); 2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = NewNode(op, arity, all); 2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return value; 2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildLocalActivationContext(Node* context) { 2263f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeclarationScope* scope = info()->scope(); 2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate a new local context. 2266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* local_context = scope->is_script_scope() 2267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? BuildLocalScriptContext(scope) 2268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : BuildLocalFunctionContext(scope); 2269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) { 2271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* receiver = environment()->RawParameterLookup(0); 2272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Context variable (at bottom of the context chain). 2273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Variable* variable = scope->receiver(); 2274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); 2275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = javascript()->StoreContext(0, variable->index()); 227662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* node = NewNode(op, receiver); 227762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch NodeProperties::ReplaceContextInput(node, local_context); 2278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy parameters into context if necessary. 2281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int num_parameters = scope->num_parameters(); 2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < num_parameters; i++) { 2283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Variable* variable = scope->parameter(i); 2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!variable->IsContextSlot()) continue; 2285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* parameter = environment()->RawParameterLookup(i + 1); 2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Context variable (at bottom of the context chain). 2287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); 2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operator* op = javascript()->StoreContext(0, variable->index()); 228962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* node = NewNode(op, parameter); 229062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch NodeProperties::ReplaceContextInput(node, local_context); 2291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return local_context; 2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildLocalFunctionContext(Scope* scope) { 2298bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(scope->is_function_scope() || scope->is_eval_scope()); 2299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Allocate a new local context. 2301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int slot_count = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 230262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const Operator* op = 230362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch javascript()->CreateFunctionContext(slot_count, scope->scope_type()); 2304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* local_context = NewNode(op, GetFunctionClosure()); 2305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return local_context; 2307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildLocalScriptContext(Scope* scope) { 2311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(scope->is_script_scope()); 2312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Allocate a new local context. 2314f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<ScopeInfo> scope_info = scope->scope_info(); 2315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = javascript()->CreateScriptContext(scope_info); 2316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* local_context = NewNode(op, GetFunctionClosure()); 2317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrepareFrameState(local_context, BailoutId::ScriptContext(), 2318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutputFrameStateCombine::Push()); 2319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return local_context; 2321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildLocalBlockContext(Scope* scope) { 2325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(scope->is_block_scope()); 2326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Allocate a new local context. 2328f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<ScopeInfo> scope_info = scope->scope_info(); 2329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = javascript()->CreateBlockContext(scope_info); 2330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* local_context = NewNode(op, GetFunctionClosureForContext()); 2331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return local_context; 2333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) { 2337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (arguments == nullptr) return nullptr; 2338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate and initialize a new arguments object. 2340109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CreateArgumentsType type = 2341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch is_strict(language_mode()) || !info()->has_simple_parameters() 2342109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ? CreateArgumentsType::kUnmappedArguments 2343109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch : CreateArgumentsType::kMappedArguments; 2344109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const Operator* op = javascript()->CreateArguments(type); 2345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* object = NewNode(op, GetFunctionClosure()); 2346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrepareFrameState(object, BailoutId::None()); 2347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Assign the object to the {arguments} variable. This should never lazy 2349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // deopt, so it is fine to send invalid bailout id. 2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); 2351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildVariableAssignment(arguments, object, Token::ASSIGN, VectorSlotPair(), 235213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch BailoutId::None()); 2353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return object; 2354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildHoleCheckThenThrow(Node* value, Variable* variable, 2357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* not_hole, 2358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BailoutId bailout_id) { 2359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder hole_check(this); 2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* the_hole = jsgraph()->TheHoleConstant(); 2361f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* check = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), 236213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch value, the_hole); 2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hole_check.If(check); 2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hole_check.Then(); 2365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* error = BuildThrowReferenceError(variable, bailout_id); 2366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Push(error); 2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hole_check.Else(); 2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Push(not_hole); 2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hole_check.End(); 2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return environment()->Pop(); 2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildHoleCheckElseThrow(Node* value, Variable* variable, 2375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* for_hole, 2376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BailoutId bailout_id) { 2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IfBuilder hole_check(this); 2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* the_hole = jsgraph()->TheHoleConstant(); 2379f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* check = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), 238013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch value, the_hole); 2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hole_check.If(check); 2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hole_check.Then(); 2383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Push(for_hole); 2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hole_check.Else(); 2385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* error = BuildThrowReferenceError(variable, bailout_id); 2386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->Push(error); 2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hole_check.End(); 2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return environment()->Pop(); 2389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::BuildVariableLoad(Variable* variable, 2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId bailout_id, 2393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const VectorSlotPair& feedback, 2394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutputFrameStateCombine combine, 2395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TypeofMode typeof_mode) { 2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* the_hole = jsgraph()->TheHoleConstant(); 2397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (variable->location()) { 2398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::UNALLOCATED: { 2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Global var, const, or let variable. 2400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> name = variable->name(); 2401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (Node* node = TryLoadGlobalConstant(name)) return node; 2402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* value = BuildGlobalLoad(name, feedback, typeof_mode); 240313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareFrameState(value, bailout_id, combine); 2404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return value; 2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::PARAMETER: 2407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::LOCAL: { 2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Local var, const, or let variable. 2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = environment()->Lookup(variable); 2410f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (variable->binding_needs_init()) { 2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Perform check for uninitialized let/const variables. 2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value->op() == the_hole->op()) { 2413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value = BuildThrowReferenceError(variable, bailout_id); 2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (value->opcode() == IrOpcode::kPhi) { 2415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value = BuildHoleCheckThenThrow(value, variable, value, bailout_id); 2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return value; 2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::CONTEXT: { 2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Context variable (potentially up the context chain). 2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int depth = current_scope()->ContextChainLength(variable->scope()); 2423c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // TODO(mstarzinger): The {maybe_assigned} flag computed during variable 2424c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // resolution is highly inaccurate and cannot be trusted. We are only 2425c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // taking this information into account when asm.js compilation is used. 2426c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch bool immutable = variable->maybe_assigned() == kNotAssigned && 2427c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch info()->is_function_context_specializing(); 2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operator* op = 2429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch javascript()->LoadContext(depth, variable->index(), immutable); 243062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* value = NewNode(op); 2431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(titzer): initialization checks are redundant for already 2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // initialized immutable context loads, but only specialization knows. 2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Maybe specializer should be a parameter to the graph builder? 2434f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (variable->binding_needs_init()) { 2435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Perform check for uninitialized let/const variables. 2436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value = BuildHoleCheckThenThrow(value, variable, value, bailout_id); 2437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return value; 2439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 244062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case VariableLocation::LOOKUP: 2441f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case VariableLocation::MODULE: 2442f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 2445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return nullptr; 2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildVariableDelete(Variable* variable, 2450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BailoutId bailout_id, 2451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutputFrameStateCombine combine) { 2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (variable->location()) { 2453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::UNALLOCATED: { 2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Global var, const, or let variable. 2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* global = BuildLoadGlobalObject(); 2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* name = jsgraph()->Constant(variable->name()); 2457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = javascript()->DeleteProperty(language_mode()); 2458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* result = NewNode(op, global, name); 2459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrepareFrameState(result, bailout_id, combine); 2460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return result; 2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::PARAMETER: 2463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::LOCAL: 2464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::CONTEXT: { 2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Local var, const, or let variable or context variable. 2466f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return jsgraph()->BooleanConstant(variable->is_this()); 2467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 246862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case VariableLocation::LOOKUP: 2469f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case VariableLocation::MODULE: 2470f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 2473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return nullptr; 2474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierNode* AstGraphBuilder::BuildVariableAssignment( 2477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Variable* variable, Node* value, Token::Value op, 2478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const VectorSlotPair& feedback, BailoutId bailout_id, 247913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch OutputFrameStateCombine combine) { 2480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* the_hole = jsgraph()->TheHoleConstant(); 2481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VariableMode mode = variable->mode(); 2482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (variable->location()) { 2483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::UNALLOCATED: { 2484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Global var, const, or let variable. 2485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> name = variable->name(); 2486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* store = BuildGlobalStore(name, value, feedback); 248713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareFrameState(store, bailout_id, combine); 2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return store; 2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::PARAMETER: 2491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::LOCAL: 2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Local var, const, or let variable. 2493f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (mode == LET && op == Token::INIT) { 2494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // No initialization check needed because scoping guarantees it. Note 2495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // that we still perform a lookup to keep the variable live, because 2496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // baseline code might contain debug code that inspects the variable. 2497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* current = environment()->Lookup(variable); 2498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_NOT_NULL(current); 2499f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (mode == LET && op != Token::INIT && 2500f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch variable->binding_needs_init()) { 2501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Perform an initialization check for let declared variables. 2502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* current = environment()->Lookup(variable); 2503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current->op() == the_hole->op()) { 2504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return BuildThrowReferenceError(variable, bailout_id); 2505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (current->opcode() == IrOpcode::kPhi) { 2506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildHoleCheckThenThrow(current, variable, value, bailout_id); 2507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (mode == CONST && op == Token::INIT) { 2509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Perform an initialization check for const {this} variables. 2510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Note that the {this} variable is the only const variable being able 2511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to trigger bind operations outside the TDZ, via {super} calls. 2512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* current = environment()->Lookup(variable); 2513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (current->op() != the_hole->op() && variable->is_this()) { 2514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value = BuildHoleCheckElseThrow(current, variable, value, bailout_id); 2515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2516f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } else if (mode == CONST && op != Token::INIT && 2517f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch variable->is_sloppy_function_name()) { 2518f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Non-initializing assignment to sloppy function names is 2519f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // - exception in strict mode. 2520f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // - ignored in sloppy mode. 2521f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(!variable->binding_needs_init()); 2522f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (variable->throw_on_const_assignment(language_mode())) { 2523f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return BuildThrowConstAssignError(bailout_id); 2524f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 2525f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return value; 2526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (mode == CONST && op != Token::INIT) { 2527f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (variable->binding_needs_init()) { 2528f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* current = environment()->Lookup(variable); 2529f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (current->op() == the_hole->op()) { 2530f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return BuildThrowReferenceError(variable, bailout_id); 2531f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (current->opcode() == IrOpcode::kPhi) { 2532f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BuildHoleCheckThenThrow(current, variable, value, bailout_id); 2533f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2535f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Assignment to const is exception in all modes. 2536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return BuildThrowConstAssignError(bailout_id); 2537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch environment()->Bind(variable, value); 2539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return value; 2540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case VariableLocation::CONTEXT: { 2541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Context variable (potentially up the context chain). 2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int depth = current_scope()->ContextChainLength(variable->scope()); 2543f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (mode == LET && op != Token::INIT && variable->binding_needs_init()) { 2544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Perform an initialization check for let declared variables. 2545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operator* op = 2546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch javascript()->LoadContext(depth, variable->index(), false); 254762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* current = NewNode(op); 2548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value = BuildHoleCheckThenThrow(current, variable, value, bailout_id); 2549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (mode == CONST && op == Token::INIT) { 2550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Perform an initialization check for const {this} variables. 2551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Note that the {this} variable is the only const variable being able 2552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to trigger bind operations outside the TDZ, via {super} calls. 2553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (variable->is_this()) { 2554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = 2555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch javascript()->LoadContext(depth, variable->index(), false); 255662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* current = NewNode(op); 2557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value = BuildHoleCheckElseThrow(current, variable, value, bailout_id); 2558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2559f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } else if (mode == CONST && op != Token::INIT && 2560f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch variable->is_sloppy_function_name()) { 2561f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Non-initializing assignment to sloppy function names is 2562f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // - exception in strict mode. 2563f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // - ignored in sloppy mode. 2564f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(!variable->binding_needs_init()); 2565f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (variable->throw_on_const_assignment(language_mode())) { 2566f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return BuildThrowConstAssignError(bailout_id); 2567f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 2568f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return value; 2569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (mode == CONST && op != Token::INIT) { 2570f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (variable->binding_needs_init()) { 2571f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const Operator* op = 2572f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch javascript()->LoadContext(depth, variable->index(), false); 257362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* current = NewNode(op); 2574f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BuildHoleCheckThenThrow(current, variable, value, bailout_id); 2575f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Assignment to const is exception in all modes. 2577958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return BuildThrowConstAssignError(bailout_id); 2578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operator* op = javascript()->StoreContext(depth, variable->index()); 258062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return NewNode(op, value); 2581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 258262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case VariableLocation::LOOKUP: 2583f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case VariableLocation::MODULE: 2584f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 2585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 2587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return nullptr; 2588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key, 2592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const VectorSlotPair& feedback) { 2593109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const Operator* op = javascript()->LoadProperty(feedback); 259462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* node = NewNode(op, object, key); 2595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return node; 2596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name, 2600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const VectorSlotPair& feedback) { 2601109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const Operator* op = javascript()->LoadNamed(name, feedback); 260262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* node = NewNode(op, object); 2603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return node; 2604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildKeyedStore(Node* object, Node* key, Node* value, 2608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const VectorSlotPair& feedback) { 260962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(feedback.vector()->GetLanguageMode(feedback.slot()), 261062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch language_mode()); 2611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = javascript()->StoreProperty(language_mode(), feedback); 261262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* node = NewNode(op, object, key, value); 2613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return node; 2614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name, 2618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* value, 2619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const VectorSlotPair& feedback) { 262062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(feedback.vector()->GetLanguageMode(feedback.slot()), 262162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch language_mode()); 2622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = 2623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch javascript()->StoreNamed(language_mode(), name, feedback); 262462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* node = NewNode(op, object, value); 2625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return node; 2626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 262862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* AstGraphBuilder::BuildNamedStoreOwn(Node* object, Handle<Name> name, 262962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* value, 263062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const VectorSlotPair& feedback) { 263162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(FeedbackSlotKind::kStoreOwnNamed, 263262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch feedback.vector()->GetKind(feedback.slot())); 263362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const Operator* op = javascript()->StoreNamedOwn(name, feedback); 263462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* node = NewNode(op, object, value); 2635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return node; 2636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildGlobalLoad(Handle<Name> name, 2639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const VectorSlotPair& feedback, 2640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TypeofMode typeof_mode) { 264162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(feedback.vector()->GetTypeofMode(feedback.slot()), typeof_mode); 2642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode); 264362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* node = NewNode(op); 2644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return node; 2645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildGlobalStore(Handle<Name> name, Node* value, 2649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const VectorSlotPair& feedback) { 2650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = 2651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch javascript()->StoreGlobal(language_mode(), name, feedback); 265262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* node = NewNode(op, value); 2653109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return node; 2654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNode* AstGraphBuilder::BuildLoadGlobalObject() { 2657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return BuildLoadNativeContextField(Context::EXTENSION_INDEX); 2658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildLoadNativeContextField(int index) { 2662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = 2663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true); 266462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* native_context = NewNode(op); 266562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* result = NewNode(javascript()->LoadContext(0, index, true)); 266662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch NodeProperties::ReplaceContextInput(result, native_context); 266762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return result; 2668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildToBoolean(Node* input, TypeFeedbackId feedback_id) { 2672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (Node* node = TryFastToBoolean(input)) return node; 267362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ToBooleanHints hints = ToBooleanHint::kAny; 2674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return NewNode(javascript()->ToBoolean(hints), input); 2675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildToObject(Node* input, BailoutId bailout_id) { 2679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* object = NewNode(javascript()->ToObject(), input); 2680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrepareFrameState(object, bailout_id, OutputFrameStateCombine::Push()); 2681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return object; 2682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildSetHomeObject(Node* value, Node* home_object, 2685f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch LiteralProperty* property, 2686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int slot_number) { 2687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Expression* expr = property->value(); 2688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!FunctionLiteral::NeedsHomeObject(expr)) return value; 2689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> name = isolate()->factory()->home_object_symbol(); 2690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VectorSlotPair feedback = 2691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CreateVectorSlotPair(property->GetSlot(slot_number)); 2692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* store = BuildNamedStore(value, name, home_object, feedback); 269313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrepareFrameState(store, BailoutId::None(), 269413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch OutputFrameStateCombine::Ignore()); 2695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return store; 2696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildThrowError(Node* exception, BailoutId bailout_id) { 2700109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const Operator* op = javascript()->CallRuntime(Runtime::kThrow); 2701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* call = NewNode(op, exception); 2702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrepareFrameState(call, bailout_id); 2703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NewNode(common()->Throw(), call); 2704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UpdateControlDependencyToLeaveFunction(control); 2705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return call; 2706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2709958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierNode* AstGraphBuilder::BuildThrowReferenceError(Variable* variable, 2710958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BailoutId bailout_id) { 2711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* variable_name = jsgraph()->Constant(variable->name()); 2712109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const Operator* op = javascript()->CallRuntime(Runtime::kThrowReferenceError); 2713958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* call = NewNode(op, variable_name); 2714958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrepareFrameState(call, bailout_id); 2715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NewNode(common()->Throw(), call); 2716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UpdateControlDependencyToLeaveFunction(control); 2717958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return call; 2718958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2719958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2720958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2721958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierNode* AstGraphBuilder::BuildThrowConstAssignError(BailoutId bailout_id) { 2722958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const Operator* op = 2723109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch javascript()->CallRuntime(Runtime::kThrowConstAssignError); 2724958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* call = NewNode(op); 2725958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrepareFrameState(call, bailout_id); 2726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NewNode(common()->Throw(), call); 2727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UpdateControlDependencyToLeaveFunction(control); 2728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return call; 2729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildReturn(Node* return_value) { 2733109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Emit tracing call if requested to do so. 2734109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (FLAG_trace) { 2735109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return_value = 2736109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch NewNode(javascript()->CallRuntime(Runtime::kTraceExit), return_value); 2737109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 2738c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* pop_node = jsgraph()->ZeroConstant(); 2739c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* control = NewNode(common()->Return(), pop_node, return_value); 2740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UpdateControlDependencyToLeaveFunction(control); 2741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return control; 2742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildThrow(Node* exception_value) { 2746109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch NewNode(javascript()->CallRuntime(Runtime::kReThrow), exception_value); 2747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NewNode(common()->Throw(), exception_value); 2748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UpdateControlDependencyToLeaveFunction(control); 2749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return control; 2750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op, 2754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TypeFeedbackId feedback_id) { 2755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operator* js_op; 275662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BinaryOperationHint hint = BinaryOperationHint::kAny; 2757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (op) { 2758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::BIT_OR: 275962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch js_op = javascript()->BitwiseOr(); 2760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::BIT_AND: 276262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch js_op = javascript()->BitwiseAnd(); 2763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::BIT_XOR: 276562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch js_op = javascript()->BitwiseXor(); 2766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::SHL: 276862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch js_op = javascript()->ShiftLeft(); 2769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::SAR: 277162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch js_op = javascript()->ShiftRight(); 2772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::SHR: 277462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch js_op = javascript()->ShiftRightLogical(); 2775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::ADD: 2777f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch js_op = javascript()->Add(hint); 2778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::SUB: 278062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch js_op = javascript()->Subtract(); 2781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::MUL: 278362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch js_op = javascript()->Multiply(); 2784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::DIV: 278662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch js_op = javascript()->Divide(); 2787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case Token::MOD: 278962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch js_op = javascript()->Modulus(); 2790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 2792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 2793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch js_op = nullptr; 2794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NewNode(js_op, left, right); 2796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::TryLoadGlobalConstant(Handle<Name> name) { 2800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Optimize global constants like "undefined", "Infinity", and "NaN". 2801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> constant_value = isolate()->factory()->GlobalConstantFor(name); 2802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!constant_value.is_null()) return jsgraph()->Constant(constant_value); 2803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return nullptr; 2804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::TryFastToBoolean(Node* input) { 2807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (input->opcode()) { 2808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kNumberConstant: { 2809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NumberMatcher m(input); 2810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return jsgraph_->BooleanConstant(!m.Is(0) && !m.IsNaN()); 2811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kHeapConstant: { 2813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<HeapObject> object = HeapObjectMatcher(input).Value(); 2814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return jsgraph_->BooleanConstant(object->BooleanValue()); 2815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSEqual: 2817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSNotEqual: 2818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSStrictEqual: 2819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSStrictNotEqual: 2820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSLessThan: 2821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSLessThanOrEqual: 2822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSGreaterThan: 2823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSGreaterThanOrEqual: 2824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSToBoolean: 2825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSDeleteProperty: 2826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSHasProperty: 2827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSInstanceOf: 2828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return input; 2829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 2830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return nullptr; 2833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool AstGraphBuilder::CheckOsrEntry(IterationStatement* stmt) { 2837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info()->osr_ast_id() == stmt->OsrEntryId()) { 2838f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK_EQ(-1, info()->osr_expr_stack_height()); 2839f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch info()->set_osr_expr_stack_height(environment()->stack_height()); 2840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 2841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 2843958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2845958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id, 2847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OutputFrameStateCombine combine) { 2848f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (OperatorProperties::HasFrameStateInput(node->op())) { 2849f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(ast_id.IsNone() || info()->shared_info()->VerifyBailoutId(ast_id)); 2850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); 2851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(IrOpcode::kDead, 2852f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::GetFrameStateInput(node)->opcode()); 2853f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool has_exception = NodeProperties::IsExceptionalCall(node); 2854f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* state = environment()->Checkpoint(ast_id, combine, has_exception); 2855f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ReplaceFrameStateInput(node, state); 2856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 285913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid AstGraphBuilder::PrepareEagerCheckpoint(BailoutId ast_id) { 286013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (environment()->GetEffectDependency()->opcode() == IrOpcode::kCheckpoint) { 286113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // We skip preparing a checkpoint if there already is one the current effect 286213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // dependency. This is just an optimization and not need for correctness. 286313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return; 286413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 286513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (ast_id != BailoutId::None()) { 2866f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(info()->shared_info()->VerifyBailoutId(ast_id)); 286713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* node = NewNode(common()->Checkpoint()); 286813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(IrOpcode::kDead, 2869f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::GetFrameStateInput(node)->opcode()); 2870f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* state = environment()->Checkpoint(ast_id); 2871f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ReplaceFrameStateInput(node, state); 287213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 287313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 2874958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2875958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierBitVector* AstGraphBuilder::GetVariablesAssignedInLoop( 2876958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier IterationStatement* stmt) { 2877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (loop_assignment_analysis_ == nullptr) return nullptr; 2878958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); 2879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2880958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode** AstGraphBuilder::EnsureInputBufferSize(int size) { 2883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (size > input_buffer_size_) { 2884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size = size + kInputBufferSizeIncrement + input_buffer_size_; 2885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch input_buffer_ = local_zone()->NewArray<Node*>(size); 2886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch input_buffer_size_ = size; 2887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return input_buffer_; 2889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count, 2893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node** value_inputs, bool incomplete) { 2894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(op->ValueInputCount(), value_input_count); 2895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool has_context = OperatorProperties::HasContextInput(op); 2897f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool has_frame_state = OperatorProperties::HasFrameStateInput(op); 2898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool has_control = op->ControlInputCount() == 1; 2899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool has_effect = op->EffectInputCount() == 1; 2900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(op->ControlInputCount() < 2); 2902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(op->EffectInputCount() < 2); 2903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* result = nullptr; 2905f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!has_context && !has_frame_state && !has_control && !has_effect) { 2906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch result = graph()->NewNode(op, value_input_count, value_inputs, incomplete); 2907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int input_count_with_deps = value_input_count; 2909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (has_context) ++input_count_with_deps; 2910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (has_frame_state) ++input_count_with_deps; 2911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (has_control) ++input_count_with_deps; 2912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (has_effect) ++input_count_with_deps; 2913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node** buffer = EnsureInputBufferSize(input_count_with_deps); 2914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch memcpy(buffer, value_inputs, kPointerSize * value_input_count); 2915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node** current_input = buffer + value_input_count; 2916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (has_context) { 2917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *current_input++ = current_context(); 2918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2919f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (has_frame_state) { 2920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The frame state will be inserted later. Here we misuse 2921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the {Dead} node as a sentinel to be later overwritten 2922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // with the real frame state. 2923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *current_input++ = jsgraph()->Dead(); 2924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (has_effect) { 2926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *current_input++ = environment_->GetEffectDependency(); 2927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (has_control) { 2929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *current_input++ = environment_->GetControlDependency(); 2930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete); 2932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!environment()->IsMarkedAsUnreachable()) { 2933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Update the current control dependency for control-producing nodes. 2934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (NodeProperties::IsControl(result)) { 2935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment_->UpdateControlDependency(result); 2936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Update the current effect dependency for effect-producing nodes. 2938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (result->op()->EffectOutputCount() > 0) { 2939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment_->UpdateEffectDependency(result); 2940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Add implicit success continuation for throwing nodes. 2942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!result->op()->HasProperty(Operator::kNoThrow)) { 2943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = common()->IfSuccess(); 2944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* on_success = graph()->NewNode(op, result); 2945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment_->UpdateControlDependency(on_success); 2946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result; 2951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { 2955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (environment()->IsMarkedAsUnreachable()) return; 2956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch environment()->MarkAsUnreachable(); 2957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch exit_controls_.push_back(exit); 2958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid AstGraphBuilder::Environment::Merge(Environment* other) { 2962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(values_.size() == other->values_.size()); 2963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(contexts_.size() == other->contexts_.size()); 2964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Nothing to do if the other environment is dead. 2966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (other->IsMarkedAsUnreachable()) return; 2967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Resurrect a dead environment by copying the contents of the other one and 2969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // placing a singleton merge as the new control dependency. 2970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (this->IsMarkedAsUnreachable()) { 2971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* other_control = other->control_dependency_; 2972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* inputs[] = {other_control}; 2973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch control_dependency_ = 2974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true); 2975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch effect_dependency_ = other->effect_dependency_; 2976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch values_ = other->values_; 2977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch contexts_ = other->contexts_; 2978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsLivenessAnalysisEnabled()) { 2979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch liveness_block_ = 2980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder_->liveness_analyzer()->NewBlock(other->liveness_block()); 2981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 2983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Record the merge for the local variable liveness calculation. 2986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // For loops, we are connecting a back edge into the existing block; 2987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // for merges, we create a new merged block. 2988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsLivenessAnalysisEnabled()) { 2989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (GetControlDependency()->opcode() != IrOpcode::kLoop) { 2990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch liveness_block_ = 2991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder_->liveness_analyzer()->NewBlock(liveness_block()); 2992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch liveness_block()->AddPredecessor(other->liveness_block()); 2994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Create a merge of the control dependencies of both environments and update 2997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the current environment's control dependency accordingly. 2998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = builder_->MergeControl(this->GetControlDependency(), 2999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch other->GetControlDependency()); 3000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UpdateControlDependency(control); 3001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Create a merge of the effect dependencies of both environments and update 3003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the current environment's effect dependency accordingly. 3004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = builder_->MergeEffect(this->GetEffectDependency(), 3005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch other->GetEffectDependency(), control); 3006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UpdateEffectDependency(effect); 3007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Introduce Phi nodes for values that have differing input at merge points, 3009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // potentially extending an existing Phi node if possible. 3010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < static_cast<int>(values_.size()); ++i) { 3011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch values_[i] = builder_->MergeValue(values_[i], other->values_[i], control); 3012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < static_cast<int>(contexts_.size()); ++i) { 3014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch contexts_[i] = 3015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder_->MergeValue(contexts_[i], other->contexts_[i], control); 3016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3019f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid AstGraphBuilder::Environment::PrepareForOsrEntry() { 3020f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int size = static_cast<int>(values()->size()); 3021f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Graph* graph = builder_->graph(); 3022f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 3023f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Set the control and effect to the OSR loop entry. 3024f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* osr_loop_entry = graph->NewNode(builder_->common()->OsrLoopEntry(), 3025f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph->start(), graph->start()); 3026f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch UpdateControlDependency(osr_loop_entry); 3027f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch UpdateEffectDependency(osr_loop_entry); 3028c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 3029f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Set OSR values. 3030f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch for (int i = 0; i < size; ++i) { 3031f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch values()->at(i) = 3032f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph->NewNode(builder_->common()->OsrValue(i), osr_loop_entry); 3033f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 3034f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 3035c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Set the innermost context. 3036c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch const Operator* op_inner = 3037c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch builder_->common()->OsrValue(Linkage::kOsrContextSpillSlotIndex); 3038c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch contexts()->back() = graph->NewNode(op_inner, osr_loop_entry); 3039c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 3040c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Create a checkpoint. 3041c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* frame_state = Checkpoint(builder_->info()->osr_ast_id()); 3042c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* checkpoint = graph->NewNode(common()->Checkpoint(), frame_state, 3043c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch osr_loop_entry, osr_loop_entry); 3044c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch UpdateEffectDependency(checkpoint); 3045c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 3046c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Create the OSR guard nodes. 3047c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch const Operator* guard_op = 3048c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch builder_->info()->is_deoptimization_enabled() 3049c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ? builder_->common()->OsrGuard(OsrGuardType::kUninitialized) 3050c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch : builder_->common()->OsrGuard(OsrGuardType::kAny); 3051c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* effect = checkpoint; 3052c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch for (int i = 0; i < size; ++i) { 3053c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch values()->at(i) = effect = 3054c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch graph->NewNode(guard_op, values()->at(i), effect, osr_loop_entry); 3055c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 3056c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch contexts()->back() = effect = 3057c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch graph->NewNode(guard_op, contexts()->back(), effect, osr_loop_entry); 3058c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 3059f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // The innermost context is the OSR value, and the outer contexts are 3060f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // reconstructed by dynamically walking up the context chain. 3061c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch const Operator* load_op = 3062f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true); 3063c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* osr_context = effect = contexts()->back(); 3064f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int last = static_cast<int>(contexts()->size() - 1); 3065c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch for (int i = last - 1; i >= 0; i--) { 306662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch osr_context = effect = graph->NewNode(load_op, osr_context, effect); 3067f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch contexts()->at(i) = osr_context; 3068f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 3069c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch UpdateEffectDependency(effect); 3070f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 3071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3072f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned) { 3073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int size = static_cast<int>(values()->size()); 3074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = builder_->NewLoop(); 3076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (assigned == nullptr) { 3077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Assume that everything is updated in the loop. 3078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < size; ++i) { 3079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch values()->at(i) = builder_->NewPhi(1, values()->at(i), control); 3080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Only build phis for those locals assigned in this loop. 3083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < size; ++i) { 3084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (i < assigned->length() && !assigned->Contains(i)) continue; 3085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* phi = builder_->NewPhi(1, values()->at(i), control); 3086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch values()->at(i) = phi; 3087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = builder_->NewEffectPhi(1, GetEffectDependency(), control); 3090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UpdateEffectDependency(effect); 3091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Connect the loop to end via Terminate if it's not marked as unreachable. 3093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!IsMarkedAsUnreachable()) { 3094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Connect the Loop node to end via a Terminate node. 3095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* terminate = builder_->graph()->NewNode( 3096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder_->common()->Terminate(), effect, control); 3097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch builder_->exit_controls_.push_back(terminate); 3098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (builder_->info()->is_osr()) { 3101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Introduce phis for all context values in the case of an OSR graph. 3102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t i = 0; i < contexts()->size(); ++i) { 3103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* context = contexts()->at(i); 3104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch contexts()->at(i) = builder_->NewPhi(1, context, control); 3105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::NewPhi(int count, Node* input, Node* control) { 3111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count); 3112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node** buffer = EnsureInputBufferSize(count + 1); 3113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemsetPointer(buffer, input, count); 3114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer[count] = control; 3115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return graph()->NewNode(phi_op, count + 1, buffer, true); 3116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::NewEffectPhi(int count, Node* input, Node* control) { 3120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* phi_op = common()->EffectPhi(count); 3121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node** buffer = EnsureInputBufferSize(count + 1); 3122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemsetPointer(buffer, input, count); 3123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer[count] = control; 3124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return graph()->NewNode(phi_op, count + 1, buffer, true); 3125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::MergeControl(Node* control, Node* other) { 3129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int inputs = control->op()->ControlInputCount() + 1; 3130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (control->opcode() == IrOpcode::kLoop) { 3131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Control node for loop exists, add input. 3132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = common()->Loop(inputs); 3133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch control->AppendInput(graph_zone(), other); 3134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp(control, op); 3135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (control->opcode() == IrOpcode::kMerge) { 3136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Control node for merge exists, add input. 3137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = common()->Merge(inputs); 3138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch control->AppendInput(graph_zone(), other); 3139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp(control, op); 3140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Control node is a singleton, introduce a merge. 3142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operator* op = common()->Merge(inputs); 3143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* inputs[] = {control, other}; 3144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch control = graph()->NewNode(op, arraysize(inputs), inputs, true); 3145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return control; 3147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::MergeEffect(Node* value, Node* other, Node* control) { 3151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int inputs = control->op()->ControlInputCount(); 3152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (value->opcode() == IrOpcode::kEffectPhi && 3153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::GetControlInput(value) == control) { 3154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Phi already exists, add input. 3155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value->InsertInput(graph_zone(), inputs - 1, other); 3156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp(value, common()->EffectPhi(inputs)); 3157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (value != other) { 3158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Phi does not exist yet, introduce one. 3159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value = NewEffectPhi(inputs, value, control); 3160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value->ReplaceInput(inputs - 1, other); 3161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return value; 3163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNode* AstGraphBuilder::MergeValue(Node* value, Node* other, Node* control) { 3167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int inputs = control->op()->ControlInputCount(); 3168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (value->opcode() == IrOpcode::kPhi && 3169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::GetControlInput(value) == control) { 3170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Phi already exists, add input. 3171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value->InsertInput(graph_zone(), inputs - 1, other); 3172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp( 3173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value, common()->Phi(MachineRepresentation::kTagged, inputs)); 3174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (value != other) { 3175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Phi does not exist yet, introduce one. 3176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value = NewPhi(inputs, value, control); 3177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value->ReplaceInput(inputs - 1, other); 3178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return value; 3180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3182c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochAstGraphBuilderWithPositions::AstGraphBuilderWithPositions( 3183c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph, 3184c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch float invocation_frequency, LoopAssignmentAnalysis* loop_assignment, 318562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch SourcePositionTable* source_positions, int inlining_id) 3186c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch : AstGraphBuilder(local_zone, info, jsgraph, invocation_frequency, 318762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch loop_assignment), 3188c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch source_positions_(source_positions), 3189c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch start_position_(info->shared_info()->start_position(), inlining_id) {} 3190c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 3191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace compiler 3192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace internal 3193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace v8 3194