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 5f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/compiler/js-typed-lowering.h" 6f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 7c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/ast/modules.h" 8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/builtins/builtins-utils.h" 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/code-factory.h" 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compilation-dependencies.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/access-builder.h" 12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/js-graph.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/linkage.h" 14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/node-matchers.h" 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/node-properties.h" 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/operator-properties.h" 17f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/compiler/type-cache.h" 18f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/compiler/types.h" 1962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h" 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler { 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A helper class to simplify the process of reducing a single binop node with a 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// JSOperator. This class manages the rewriting of context, control, and effect 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// dependencies during lowering of a binop and contains numerous helper 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// functions for matching the types of inputs to an operation. 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass JSBinopReduction final { 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSBinopReduction(JSTypedLowering* lowering, Node* node) 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : lowering_(lowering), node_(node) {} 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 34f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool GetCompareNumberOperationHint(NumberOperationHint* hint) { 35f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { 36f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(1, node_->op()->EffectOutputCount()); 37f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (CompareOperationHintOf(node_->op())) { 38f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case CompareOperationHint::kSignedSmall: 39f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch *hint = NumberOperationHint::kSignedSmall; 40f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case CompareOperationHint::kNumber: 42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch *hint = NumberOperationHint::kNumber; 43f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case CompareOperationHint::kNumberOrOddball: 45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch *hint = NumberOperationHint::kNumberOrOddball; 46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case CompareOperationHint::kAny: 48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case CompareOperationHint::kNone: 4962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case CompareOperationHint::kString: 5062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case CompareOperationHint::kReceiver: 5162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case CompareOperationHint::kInternalizedString: 52f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 53f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 5413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 55f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 5613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 5713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 5862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool IsInternalizedStringCompareOperation() { 5962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { 6062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(1, node_->op()->EffectOutputCount()); 6162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return (CompareOperationHintOf(node_->op()) == 6262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CompareOperationHint::kInternalizedString) && 6362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BothInputsMaybe(Type::InternalizedString()); 6462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 6562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return false; 6662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 6762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 6862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool IsReceiverCompareOperation() { 6962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { 7062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(1, node_->op()->EffectOutputCount()); 7162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return (CompareOperationHintOf(node_->op()) == 7262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CompareOperationHint::kReceiver) && 7362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BothInputsMaybe(Type::Receiver()); 7462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 7562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return false; 7662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 7762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 7862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool IsStringCompareOperation() { 7962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { 8062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(1, node_->op()->EffectOutputCount()); 8162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return (CompareOperationHintOf(node_->op()) == 8262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CompareOperationHint::kString) && 8362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BothInputsMaybe(Type::String()); 8462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 8562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return false; 8662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 8762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 88f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if a string addition will definitely result in creating a ConsString, 89f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // i.e. if the combined length of the resulting string exceeds the ConsString 90f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // minimum length. 91f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch bool ShouldCreateConsString() { 92f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK_EQ(IrOpcode::kJSAdd, node_->opcode()); 9362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(OneInputIs(Type::String())); 94f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (BothInputsAre(Type::String()) || 95f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ((lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) && 96f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch BinaryOperationHintOf(node_->op()) == BinaryOperationHint::kString)) { 97c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HeapObjectBinopMatcher m(node_); 98c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (m.right().HasValue() && m.right().Value()->IsString()) { 99c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<String> right_string = Handle<String>::cast(m.right().Value()); 100f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (right_string->length() >= ConsString::kMinLength) return true; 101f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 102c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (m.left().HasValue() && m.left().Value()->IsString()) { 103c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<String> left_string = Handle<String>::cast(m.left().Value()); 104f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (left_string->length() >= ConsString::kMinLength) { 105f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // The invariant for ConsString requires the left hand side to be 106f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // a sequential or external string if the right hand side is the 107f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // empty string. Since we don't know anything about the right hand 108f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // side here, we must ensure that the left hand side satisfy the 109f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // constraints independent of the right hand side. 110f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return left_string->IsSeqString() || left_string->IsExternalString(); 111f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 112f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 113f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 114f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return false; 115f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 116f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 11762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Inserts a CheckReceiver for the left input. 11862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void CheckLeftInputToReceiver() { 11962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* left_input = graph()->NewNode(simplified()->CheckReceiver(), left(), 12062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch effect(), control()); 12162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node_->ReplaceInput(0, left_input); 12262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch update_effect(left_input); 12362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 12462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 12562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Checks that both inputs are Receiver, and if we don't know 12662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // statically that one side is already a Receiver, insert a 12762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // CheckReceiver node. 12862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void CheckInputsToReceiver() { 12962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!left_type()->Is(Type::Receiver())) { 13062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CheckLeftInputToReceiver(); 13162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 13262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!right_type()->Is(Type::Receiver())) { 13362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* right_input = graph()->NewNode(simplified()->CheckReceiver(), 13462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch right(), effect(), control()); 13562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node_->ReplaceInput(1, right_input); 13662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch update_effect(right_input); 13762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 13862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 13962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 14062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Checks that both inputs are String, and if we don't know 14162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // statically that one side is already a String, insert a 14262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // CheckString node. 14362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void CheckInputsToString() { 14462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!left_type()->Is(Type::String())) { 14562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* left_input = graph()->NewNode(simplified()->CheckString(), left(), 14662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch effect(), control()); 14762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node_->ReplaceInput(0, left_input); 14862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch update_effect(left_input); 14962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 15062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!right_type()->Is(Type::String())) { 15162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* right_input = graph()->NewNode(simplified()->CheckString(), right(), 15262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch effect(), control()); 15362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node_->ReplaceInput(1, right_input); 15462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch update_effect(right_input); 15562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 15662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 15762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 15862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Checks that both inputs are InternalizedString, and if we don't know 15962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // statically that one side is already an InternalizedString, insert a 16062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // CheckInternalizedString node. 16162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void CheckInputsToInternalizedString() { 16262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!left_type()->Is(Type::UniqueName())) { 16362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* left_input = graph()->NewNode( 16462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch simplified()->CheckInternalizedString(), left(), effect(), control()); 16562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node_->ReplaceInput(0, left_input); 16662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch update_effect(left_input); 16762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 16862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!right_type()->Is(Type::UniqueName())) { 16962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* right_input = 17062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch graph()->NewNode(simplified()->CheckInternalizedString(), right(), 17162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch effect(), control()); 17262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node_->ReplaceInput(1, right_input); 17362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch update_effect(right_input); 17462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 17562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 17662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ConvertInputsToNumber() { 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // To convert the inputs to numbers, we have to provide frame states 179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // for lazy bailouts in the ToNumber conversions. 180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We use a little hack here: we take the frame state before the binary 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // operation and use it to construct the frame states for the conversion 182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // so that after the deoptimization, the binary operation IC gets 183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // already converted values from full code. This way we are sure that we 184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // will not re-do any of the side effects. 185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* left_input = nullptr; 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* right_input = nullptr; 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool left_is_primitive = left_type()->Is(Type::PlainPrimitive()); 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool right_is_primitive = right_type()->Is(Type::PlainPrimitive()); 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool handles_exception = NodeProperties::IsExceptionalCall(node_); 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!left_is_primitive && !right_is_primitive && handles_exception) { 193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ConvertBothInputsToNumber(&left_input, &right_input); 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left_input = left_is_primitive 19613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ? ConvertPlainPrimitiveToNumber(left()) 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : ConvertSingleInputToNumber( 198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch left(), CreateFrameStateForLeftInput()); 199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch right_input = 200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch right_is_primitive 201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ? ConvertPlainPrimitiveToNumber(right()) 202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : ConvertSingleInputToNumber( 203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch right(), CreateFrameStateForRightInput(left_input)); 204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node_->ReplaceInput(0, left_input); 207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node_->ReplaceInput(1, right_input); 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void ConvertInputsToUI32(Signedness left_signedness, 211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Signedness right_signedness) { 212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node_->ReplaceInput(0, ConvertToUI32(left(), left_signedness)); 213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node_->ReplaceInput(1, ConvertToUI32(right(), right_signedness)); 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SwapInputs() { 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* l = left(); 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* r = right(); 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node_->ReplaceInput(0, r); 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node_->ReplaceInput(1, l); 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remove all effect and control inputs and outputs to this node and change 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to the pure operator {op}, possibly inserting a boolean inversion. 225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Reduction ChangeToPureOperator(const Operator* op, bool invert = false, 226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Type* type = Type::Any()) { 227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(0, op->EffectInputCount()); 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(false, OperatorProperties::HasContextInput(op)); 229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(0, op->ControlInputCount()); 230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(2, op->ValueInputCount()); 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Remove the effects from the node, and update its effect/control usages. 233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (node_->op()->EffectInputCount() > 0) { 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lowering_->RelaxEffectsAndControls(node_); 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remove the inputs corresponding to context, effect, and control. 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NodeProperties::RemoveNonValueInputs(node_); 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Finally, update the operator to the new one. 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp(node_, op); 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(jarin): Replace the explicit typing hack with a call to some method 242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // that encapsulates changing the operator and re-typing. 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* node_type = NodeProperties::GetType(node_); 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::SetType(node_, Type::Intersect(node_type, type, zone())); 245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (invert) { 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Insert an boolean not to invert the value. 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = graph()->NewNode(simplified()->BooleanNot(), node_); 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch node_->ReplaceUses(value); 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Note: ReplaceUses() smashes all uses, so smash it back here. 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value->ReplaceInput(0, node_); 252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return lowering_->Replace(value); 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return lowering_->Changed(node_); 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 257f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Reduction ChangeToSpeculativeOperator(const Operator* op, bool invert, 258f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Type* upper_bound) { 25913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(1, op->EffectInputCount()); 26013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(1, op->EffectOutputCount()); 26113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(false, OperatorProperties::HasContextInput(op)); 26213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(1, op->ControlInputCount()); 26313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(0, op->ControlOutputCount()); 26413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op)); 26513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(2, op->ValueInputCount()); 26613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 26713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(1, node_->op()->EffectInputCount()); 26813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(1, node_->op()->EffectOutputCount()); 26913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(1, node_->op()->ControlInputCount()); 27013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(2, node_->op()->ValueInputCount()); 27113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 27213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Reconnect the control output to bypass the IfSuccess node and 27313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // possibly disconnect from the IfException node. 27413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch for (Edge edge : node_->use_edges()) { 27513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* const user = edge.from(); 27613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!user->IsDead()); 27713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (NodeProperties::IsControlEdge(edge)) { 27813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (user->opcode() == IrOpcode::kIfSuccess) { 27913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch user->ReplaceUses(NodeProperties::GetControlInput(node_)); 28013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch user->Kill(); 28113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } else { 28213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(user->opcode(), IrOpcode::kIfException); 28313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch edge.UpdateTo(jsgraph()->Dead()); 28413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 28513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 28613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 28713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 288f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Remove the frame state and the context. 289f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (OperatorProperties::HasFrameStateInput(node_->op())) { 290f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_)); 291f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 29213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch node_->RemoveInput(NodeProperties::FirstContextIndex(node_)); 29313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 29413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch NodeProperties::ChangeOp(node_, op); 29513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 29613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Update the type to number. 29713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Type* node_type = NodeProperties::GetType(node_); 29813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch NodeProperties::SetType(node_, 29913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Type::Intersect(node_type, upper_bound, zone())); 30013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 301f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (invert) { 302f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Insert an boolean not to invert the value. 303f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* value = graph()->NewNode(simplified()->BooleanNot(), node_); 304f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node_->ReplaceUses(value); 305f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Note: ReplaceUses() smashes all uses, so smash it back here. 306f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch value->ReplaceInput(0, node_); 307f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return lowering_->Replace(value); 308f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 30913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return lowering_->Changed(node_); 31013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 31113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Reduction ChangeToPureOperator(const Operator* op, Type* type) { 313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ChangeToPureOperator(op, false, type); 314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 316f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Reduction ChangeToSpeculativeOperator(const Operator* op, Type* type) { 317f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return ChangeToSpeculativeOperator(op, false, type); 318f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 319f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 320f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const Operator* NumberOp() { 321f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (node_->opcode()) { 322f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSAdd: 323f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberAdd(); 324f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSSubtract: 325f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberSubtract(); 326f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSMultiply: 327f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberMultiply(); 328f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSDivide: 329f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberDivide(); 330f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSModulus: 331f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberModulus(); 332f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSBitwiseAnd: 333f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberBitwiseAnd(); 334f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSBitwiseOr: 335f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberBitwiseOr(); 336f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSBitwiseXor: 337f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberBitwiseXor(); 338f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSShiftLeft: 339f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberShiftLeft(); 340f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSShiftRight: 341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberShiftRight(); 342f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSShiftRightLogical: 343f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return simplified()->NumberShiftRightLogical(); 344f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch default: 345f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 346f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 347f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 348f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return nullptr; 349f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 350f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 35162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const Operator* NumberOpFromSpeculativeNumberOp() { 352f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (node_->opcode()) { 35362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case IrOpcode::kSpeculativeNumberAdd: 35462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return simplified()->NumberAdd(); 35562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case IrOpcode::kSpeculativeNumberSubtract: 35662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return simplified()->NumberSubtract(); 35762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case IrOpcode::kSpeculativeNumberMultiply: 35862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return simplified()->NumberMultiply(); 35962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case IrOpcode::kSpeculativeNumberDivide: 36062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return simplified()->NumberDivide(); 36162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case IrOpcode::kSpeculativeNumberModulus: 36262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return simplified()->NumberModulus(); 363f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch default: 364f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 365f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 366f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return nullptr; 368f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 369f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool LeftInputIs(Type* t) { return left_type()->Is(t); } 371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool RightInputIs(Type* t) { return right_type()->Is(t); } 373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool OneInputIs(Type* t) { return LeftInputIs(t) || RightInputIs(t); } 375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool BothInputsAre(Type* t) { return LeftInputIs(t) && RightInputIs(t); } 377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 37862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool BothInputsMaybe(Type* t) { 37962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return left_type()->Maybe(t) && right_type()->Maybe(t); 38062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 38162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool OneInputCannotBe(Type* t) { 383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return !left_type()->Maybe(t) || !right_type()->Maybe(t); 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool NeitherInputCanBe(Type* t) { 387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return !left_type()->Maybe(t) && !right_type()->Maybe(t); 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* effect() { return NodeProperties::GetEffectInput(node_); } 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* control() { return NodeProperties::GetControlInput(node_); } 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* context() { return NodeProperties::GetContextInput(node_); } 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* left() { return NodeProperties::GetValueInput(node_, 0); } 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* right() { return NodeProperties::GetValueInput(node_, 1); } 395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* left_type() { return NodeProperties::GetType(node_->InputAt(0)); } 396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* right_type() { return NodeProperties::GetType(node_->InputAt(1)); } 397f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Type* type() { return NodeProperties::GetType(node_); } 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SimplifiedOperatorBuilder* simplified() { return lowering_->simplified(); } 400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Graph* graph() const { return lowering_->graph(); } 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSGraph* jsgraph() { return lowering_->jsgraph(); } 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSOperatorBuilder* javascript() { return lowering_->javascript(); } 403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CommonOperatorBuilder* common() { return jsgraph()->common(); } 404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Zone* zone() const { return graph()->zone(); } 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSTypedLowering* lowering_; // The containing lowering instance. 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* node_; // The original node. 409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 410f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* CreateFrameStateForLeftInput() { 411f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Deoptimization is disabled => return dummy frame state instead. 412f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* dummy_state = NodeProperties::GetFrameStateInput(node_); 413f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone()); 414f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return dummy_state; 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 417f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* CreateFrameStateForRightInput(Node* converted_left) { 418f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Deoptimization is disabled => return dummy frame state instead. 419f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* dummy_state = NodeProperties::GetFrameStateInput(node_); 420f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone()); 421f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return dummy_state; 422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 42413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* ConvertPlainPrimitiveToNumber(Node* node) { 425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(NodeProperties::GetType(node)->Is(Type::PlainPrimitive())); 426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Avoid inserting too many eager ToNumber() operations. 427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Reduction const reduction = lowering_->ReduceJSToNumberInput(node); 428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (reduction.Changed()) return reduction.replacement(); 42913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (NodeProperties::GetType(node)->Is(Type::Number())) { 430bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return node; 431bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 43213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return graph()->NewNode(simplified()->PlainPrimitiveToNumber(), node); 433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* ConvertSingleInputToNumber(Node* node, Node* frame_state) { 436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!NodeProperties::GetType(node)->Is(Type::PlainPrimitive())); 437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* const n = graph()->NewNode(javascript()->ToNumber(), node, context(), 438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_state, effect(), control()); 439bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* const if_success = graph()->NewNode(common()->IfSuccess(), n); 440bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NodeProperties::ReplaceControlInput(node_, if_success); 441bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NodeProperties::ReplaceUses(node_, node_, node_, node_, n); 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch update_effect(n); 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return n; 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 446f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ConvertBothInputsToNumber(Node** left_result, Node** right_result) { 447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* projections[2]; 448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Find {IfSuccess} and {IfException} continuations of the operation. 450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::CollectControlProjections(node_, projections, 2); 451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* if_exception = projections[1]; 452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* if_success = projections[0]; 453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Insert two ToNumber() operations that both potentially throw. 455f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* left_state = CreateFrameStateForLeftInput(); 456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* left_conv = 457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(javascript()->ToNumber(), left(), context(), 458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left_state, effect(), control()); 459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* left_success = graph()->NewNode(common()->IfSuccess(), left_conv); 460f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* right_state = CreateFrameStateForRightInput(left_conv); 461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* right_conv = 462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(javascript()->ToNumber(), right(), context(), 463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch right_state, left_conv, left_success); 464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* left_exception = 465f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->IfException(), left_conv, left_conv); 466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* right_exception = 467f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->IfException(), right_conv, right_conv); 468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ReplaceControlInput(if_success, right_conv); 469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch update_effect(right_conv); 470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Wire conversions to existing {IfException} continuation. 472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* exception_merge = if_exception; 473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* exception_value = 474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), 475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left_exception, right_exception, exception_merge); 476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* exception_effect = 477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(common()->EffectPhi(2), left_exception, 478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch right_exception, exception_merge); 479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (Edge edge : exception_merge->use_edges()) { 480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (NodeProperties::IsEffectEdge(edge)) edge.UpdateTo(exception_effect); 481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (NodeProperties::IsValueEdge(edge)) edge.UpdateTo(exception_value); 482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::RemoveType(exception_merge); 484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch exception_merge->ReplaceInput(0, left_exception); 485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch exception_merge->ReplaceInput(1, right_exception); 486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp(exception_merge, common()->Merge(2)); 487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *left_result = left_conv; 489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *right_result = right_conv; 490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* ConvertToUI32(Node* node, Signedness signedness) { 493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Avoid introducing too many eager NumberToXXnt32() operations. 494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* type = NodeProperties::GetType(node); 495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (signedness == kSigned) { 496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!type->Is(Type::Signed32())) { 497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node = graph()->NewNode(simplified()->NumberToInt32(), node); 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(kUnsigned, signedness); 501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!type->Is(Type::Unsigned32())) { 502958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node = graph()->NewNode(simplified()->NumberToUint32(), node); 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return node; 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void update_effect(Node* effect) { 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NodeProperties::ReplaceEffectInput(node_, effect); 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// TODO(turbofan): js-typed-lowering improvements possible 515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// - immediately put in type bounds for all new nodes 516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// - relax effects from generic but not-side-effecting operations 517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochJSTypedLowering::JSTypedLowering(Editor* editor, 519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompilationDependencies* dependencies, 520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Flags flags, JSGraph* jsgraph, Zone* zone) 521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : AdvancedReducer(editor), 522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch dependencies_(dependencies), 523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch flags_(flags), 524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph_(jsgraph), 52562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch pointer_comparable_type_(Type::Union( 52662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Type::Oddball(), 52762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Type::Union( 52862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Type::SymbolOrReceiver(), 52962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Type::HeapConstant(factory()->empty_string(), graph()->zone()), 53062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch graph()->zone()), 53162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch graph()->zone())), 532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch type_cache_(TypeCache::Get()) { 533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) { 534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double min = kMinInt / (1 << k); 535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double max = kMaxInt / (1 << k); 536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); 537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 54062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceSpeculativeNumberAdd(Node* node) { 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSBinopReduction r(this, node); 54262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch NumberOperationHint hint = NumberOperationHintOf(node->op()); 54362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (hint == NumberOperationHint::kNumberOrOddball && 54462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch r.BothInputsAre(Type::PlainPrimitive()) && 54562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch r.NeitherInputCanBe(Type::StringOrReceiver())) { 54662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // SpeculativeNumberAdd(x:-string, y:-string) => 54762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // NumberAdd(ToNumber(x), ToNumber(y)) 54862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch r.ConvertInputsToNumber(); 54962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); 55013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 55162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return NoChange(); 55262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 55362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 55462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceJSAdd(Node* node) { 55562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSBinopReduction r(this, node); 55613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (r.BothInputsAre(Type::Number())) { 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JSAdd(x:number, y:number) => NumberAdd(x, y) 558f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToNumber(); 55913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 561f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if ((r.BothInputsAre(Type::PlainPrimitive()) || 562f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch !(flags() & kDeoptimizationEnabled)) && 563f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.NeitherInputCanBe(Type::StringOrReceiver())) { 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) 565f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToNumber(); 566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); 567958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 568bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (r.OneInputIs(Type::String())) { 569f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (r.ShouldCreateConsString()) { 570f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return ReduceCreateConsString(node); 571f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 572bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch StringAddFlags flags = STRING_ADD_CHECK_NONE; 573bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!r.LeftInputIs(Type::String())) { 574bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch flags = STRING_ADD_CONVERT_LEFT; 575bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (!r.RightInputIs(Type::String())) { 576bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch flags = STRING_ADD_CONVERT_RIGHT; 577bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 57862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Operator::Properties properties = node->op()->properties(); 57962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (r.NeitherInputCanBe(Type::Receiver())) { 58062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Both sides are already strings, so we know that the 58162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // string addition will not cause any observable side 58262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // effects; it can still throw obviously. 58362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch properties = Operator::kNoWrite | Operator::kNoDeopt; 58462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 585bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // JSAdd(x:string, y) => CallStub[StringAdd](x, y) 586bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // JSAdd(x, y:string) => CallStub[StringAdd](x, y) 587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Callable const callable = 588bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CodeFactory::StringAdd(isolate(), flags, NOT_TENURED); 589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( 590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate(), graph()->zone(), callable.descriptor(), 0, 59162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CallDescriptor::kNeedsFrameState, properties); 592f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); 593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 0, 594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->HeapConstant(callable.code())); 595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp(node, common()->Call(desc)); 596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return NoChange(); 599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 600958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 601f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochReduction JSTypedLowering::ReduceNumberBinop(Node* node) { 602958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JSBinopReduction r(this, node); 603f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (r.BothInputsAre(Type::PlainPrimitive()) || 604f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch !(flags() & kDeoptimizationEnabled)) { 605f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToNumber(); 606f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(r.NumberOp(), Type::Number()); 60713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 608958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return NoChange(); 609958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 61162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceSpeculativeNumberBinop(Node* node) { 61213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch JSBinopReduction r(this, node); 61362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch NumberOperationHint hint = NumberOperationHintOf(node->op()); 61462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (hint == NumberOperationHint::kNumberOrOddball && 61562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch r.BothInputsAre(Type::NumberOrOddball())) { 61662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch r.ConvertInputsToNumber(); 61762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return r.ChangeToPureOperator(r.NumberOpFromSpeculativeNumberOp(), 61862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Type::Number()); 61913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 62062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return NoChange(); 62162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 62262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 62362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceInt32Binop(Node* node) { 62462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSBinopReduction r(this, node); 625f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (r.BothInputsAre(Type::PlainPrimitive()) || 626f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch !(flags() & kDeoptimizationEnabled)) { 627f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToNumber(); 628f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToUI32(kSigned, kSigned); 629f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(r.NumberOp(), Type::Signed32()); 63013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 631f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return NoChange(); 63213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 63313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 634f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochReduction JSTypedLowering::ReduceUI32Shift(Node* node, Signedness signedness) { 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSBinopReduction r(this, node); 636f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (r.BothInputsAre(Type::PlainPrimitive()) || 637f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch !(flags() & kDeoptimizationEnabled)) { 638f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToNumber(); 639f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToUI32(signedness, kUnsigned); 640f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(r.NumberOp(), signedness == kUnsigned 641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ? Type::Unsigned32() 642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : Type::Signed32()); 643f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 644f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return NoChange(); 645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 647f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochReduction JSTypedLowering::ReduceCreateConsString(Node* node) { 648f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* first = NodeProperties::GetValueInput(node, 0); 649f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* second = NodeProperties::GetValueInput(node, 1); 650f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* context = NodeProperties::GetContextInput(node); 651f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* frame_state = NodeProperties::GetFrameStateInput(node); 652f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 653f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 654f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 655f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Make sure {first} is actually a String. 656f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Type* first_type = NodeProperties::GetType(first); 657f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!first_type->Is(Type::String())) { 658f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch first = effect = 659f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(simplified()->CheckString(), first, effect, control); 660f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch first_type = NodeProperties::GetType(first); 661f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 662f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 663f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Make sure {second} is actually a String. 664f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Type* second_type = NodeProperties::GetType(second); 665f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!second_type->Is(Type::String())) { 666f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch second = effect = 667f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(simplified()->CheckString(), second, effect, control); 668f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch second_type = NodeProperties::GetType(second); 669f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 670f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 671f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Determine the {first} length. 672c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HeapObjectBinopMatcher m(node); 673f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* first_length = 674c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch (m.left().HasValue() && m.left().Value()->IsString()) 675f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ? jsgraph()->Constant( 676c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<String>::cast(m.left().Value())->length()) 677f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch : effect = graph()->NewNode( 678f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->LoadField(AccessBuilder::ForStringLength()), 679f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch first, effect, control); 680f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 681f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Determine the {second} length. 682f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* second_length = 683c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch (m.right().HasValue() && m.right().Value()->IsString()) 684f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ? jsgraph()->Constant( 685c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<String>::cast(m.right().Value())->length()) 686f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch : effect = graph()->NewNode( 687f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->LoadField(AccessBuilder::ForStringLength()), 688f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch second, effect, control); 689f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 690f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Compute the resulting length. 691f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* length = 692f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(simplified()->NumberAdd(), first_length, second_length); 693f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 694f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if we would overflow the allowed maximum string length. 695f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* check = graph()->NewNode(simplified()->NumberLessThanOrEqual(), length, 696f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch jsgraph()->Constant(String::kMaxLength)); 697c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (isolate()->IsStringLengthOverflowIntact()) { 698c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Add a code dependency on the string length overflow protector. 699c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch dependencies()->AssumePropertyCell(factory()->string_length_protector()); 700c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 701c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // We can just deoptimize if the {check} fails. Besides generating a 702c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // shorter code sequence than the version below, this has the additional 703c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // benefit of not holding on to the lazy {frame_state} and thus potentially 704c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // reduces the number of live ranges and allows for more truncations. 705c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control); 706c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 707c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* branch = 708c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); 709c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 710c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* efalse = effect; 711c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch { 712c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Throw a RangeError in case of overflow. 713c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* vfalse = efalse = graph()->NewNode( 714c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch javascript()->CallRuntime(Runtime::kThrowInvalidStringLength), 715c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch context, frame_state, efalse, if_false); 716c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if_false = graph()->NewNode(common()->IfSuccess(), vfalse); 717c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if_false = graph()->NewNode(common()->Throw(), vfalse, efalse, if_false); 718c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // TODO(bmeurer): This should be on the AdvancedReducer somehow. 719c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch NodeProperties::MergeControlToEnd(graph(), common(), if_false); 720c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Revisit(graph()->end()); 721c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 722c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Update potential {IfException} uses of {node} to point to the 723c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // %ThrowInvalidStringLength runtime call node instead. 724c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch for (Edge edge : node->use_edges()) { 725c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (edge.from()->opcode() == IrOpcode::kIfException) { 726c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK(NodeProperties::IsControlEdge(edge) || 727c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch NodeProperties::IsEffectEdge(edge)); 728c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch edge.UpdateTo(vfalse); 729c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Revisit(edge.from()); 730c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 731f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 732f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 733c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch control = graph()->NewNode(common()->IfTrue(), branch); 734f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 735f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 736f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Figure out the map for the resulting ConsString. 737f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // TODO(turbofan): We currently just use the cons_string_map here for 738f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // the sake of simplicity; we could also try to be smarter here and 739f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // use the one_byte_cons_string_map instead when the resulting ConsString 740f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // contains only one byte characters. 741f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* value_map = jsgraph()->HeapConstant(factory()->cons_string_map()); 742f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 743f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Allocate the resulting ConsString. 744f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect = graph()->NewNode( 745f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch common()->BeginRegion(RegionObservability::kNotObservable), effect); 746f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* value = effect = 747f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(simplified()->Allocate(NOT_TENURED), 748f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch jsgraph()->Constant(ConsString::kSize), effect, control); 749f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch NodeProperties::SetType(value, Type::OtherString()); 750f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()), 751f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch value, value_map, effect, control); 752f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect = graph()->NewNode( 753f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->StoreField(AccessBuilder::ForNameHashField()), value, 754c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch jsgraph()->Constant(Name::kEmptyHashField), effect, control); 755f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect = graph()->NewNode( 756f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->StoreField(AccessBuilder::ForStringLength()), value, length, 757f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect, control); 758f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect = graph()->NewNode( 759f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->StoreField(AccessBuilder::ForConsStringFirst()), value, 760f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch first, effect, control); 761f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect = graph()->NewNode( 762f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->StoreField(AccessBuilder::ForConsStringSecond()), value, 763f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch second, effect, control); 764f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 765f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Morph the {node} into a {FinishRegion}. 766f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ReplaceWithValue(node, node, node, control); 767f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->ReplaceInput(0, value); 768f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->ReplaceInput(1, effect); 769f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->TrimInputCount(2); 770f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch NodeProperties::ChangeOp(node, common()->FinishRegion()); 771f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return Changed(node); 772f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 773f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSComparison(Node* node) { 775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSBinopReduction r(this, node); 776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.BothInputsAre(Type::String())) { 777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If both inputs are definitely strings, perform a string comparison. 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operator* stringOp; 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (node->opcode()) { 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSLessThan: 781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stringOp = simplified()->StringLessThan(); 782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSGreaterThan: 784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stringOp = simplified()->StringLessThan(); 785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch r.SwapInputs(); // a > b => b < a 786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSLessThanOrEqual: 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stringOp = simplified()->StringLessThanOrEqual(); 789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSGreaterThanOrEqual: 791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stringOp = simplified()->StringLessThanOrEqual(); 792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch r.SwapInputs(); // a >= b => b <= a 793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 797bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch r.ChangeToPureOperator(stringOp); 798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 799958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 80013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NumberOperationHint hint; 802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const Operator* less_than; 803f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const Operator* less_than_or_equal; 804f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (r.BothInputsAre(Type::Signed32()) || 805f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.BothInputsAre(Type::Unsigned32())) { 806f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch less_than = simplified()->NumberLessThan(); 807f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch less_than_or_equal = simplified()->NumberLessThanOrEqual(); 808f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (r.GetCompareNumberOperationHint(&hint)) { 809f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch less_than = simplified()->SpeculativeNumberLessThan(hint); 810f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch less_than_or_equal = simplified()->SpeculativeNumberLessThanOrEqual(hint); 811f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (r.OneInputCannotBe(Type::StringOrReceiver()) && 812f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (r.BothInputsAre(Type::PlainPrimitive()) || 813f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch !(flags() & kDeoptimizationEnabled))) { 814f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.ConvertInputsToNumber(); 815f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch less_than = simplified()->NumberLessThan(); 816f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch less_than_or_equal = simplified()->NumberLessThanOrEqual(); 81762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (r.IsStringCompareOperation()) { 81862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch r.CheckInputsToString(); 81962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch less_than = simplified()->StringLessThan(); 82062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch less_than_or_equal = simplified()->StringLessThanOrEqual(); 821f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 822f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return NoChange(); 823f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 824f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const Operator* comparison; 825f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (node->opcode()) { 826f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSLessThan: 827f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch comparison = less_than; 828f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 829f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSGreaterThan: 830f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch comparison = less_than; 831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.SwapInputs(); // a > b => b < a 832f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 833f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSLessThanOrEqual: 834f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch comparison = less_than_or_equal; 835f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 836f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kJSGreaterThanOrEqual: 837f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch comparison = less_than_or_equal; 838f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.SwapInputs(); // a >= b => b <= a 839f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 840f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch default: 841f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return NoChange(); 842f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 843f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (comparison->EffectInputCount() > 0) { 844f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToSpeculativeOperator(comparison, Type::Boolean()); 845f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 846f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(comparison); 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 850c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochReduction JSTypedLowering::ReduceJSTypeOf(Node* node) { 851c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* const input = node->InputAt(0); 852c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Type* type = NodeProperties::GetType(input); 853c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Factory* const f = factory(); 854c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (type->Is(Type::Boolean())) { 855c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Replace(jsgraph()->Constant(f->boolean_string())); 856c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else if (type->Is(Type::Number())) { 857c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Replace(jsgraph()->Constant(f->number_string())); 858c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else if (type->Is(Type::String())) { 859c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Replace(jsgraph()->Constant(f->string_string())); 860c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else if (type->Is(Type::Symbol())) { 861c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Replace(jsgraph()->Constant(f->symbol_string())); 86262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (type->Is(Type::OtherUndetectableOrUndefined())) { 863c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Replace(jsgraph()->Constant(f->undefined_string())); 86462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (type->Is(Type::NonCallableOrNull())) { 865c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Replace(jsgraph()->Constant(f->object_string())); 866c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else if (type->Is(Type::Function())) { 867c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Replace(jsgraph()->Constant(f->function_string())); 868c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else if (type->IsHeapConstant()) { 869c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Replace(jsgraph()->Constant( 870c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Object::TypeOf(isolate(), type->AsHeapConstant()->Value()))); 871c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 872c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 873c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return NoChange(); 874c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 875c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 876bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochReduction JSTypedLowering::ReduceJSEqualTypeOf(Node* node, bool invert) { 87762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* input; 87862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<String> type; 879bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch HeapObjectBinopMatcher m(node); 880bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (m.left().IsJSTypeOf() && m.right().HasValue() && 881bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch m.right().Value()->IsString()) { 88262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch input = m.left().InputAt(0); 88362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch type = Handle<String>::cast(m.right().Value()); 88462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (m.right().IsJSTypeOf() && m.left().HasValue() && 88562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m.left().Value()->IsString()) { 88662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch input = m.right().InputAt(0); 88762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch type = Handle<String>::cast(m.left().Value()); 88862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 88962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return NoChange(); 890bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 89162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* value; 89262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (String::Equals(type, factory()->boolean_string())) { 89362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value = 89462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch graph()->NewNode(common()->Select(MachineRepresentation::kTagged), 89562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch graph()->NewNode(simplified()->ReferenceEqual(), input, 89662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch jsgraph()->TrueConstant()), 89762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch jsgraph()->TrueConstant(), 89862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch graph()->NewNode(simplified()->ReferenceEqual(), input, 89962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch jsgraph()->FalseConstant())); 90062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (String::Equals(type, factory()->function_string())) { 90162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value = graph()->NewNode(simplified()->ObjectIsDetectableCallable(), input); 90262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (String::Equals(type, factory()->number_string())) { 90362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value = graph()->NewNode(simplified()->ObjectIsNumber(), input); 90462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (String::Equals(type, factory()->object_string())) { 90562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value = graph()->NewNode( 90662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch common()->Select(MachineRepresentation::kTagged), 90762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch graph()->NewNode(simplified()->ObjectIsNonCallable(), input), 90862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch jsgraph()->TrueConstant(), 90962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch graph()->NewNode(simplified()->ReferenceEqual(), input, 91062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch jsgraph()->NullConstant())); 91162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (String::Equals(type, factory()->string_string())) { 91262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value = graph()->NewNode(simplified()->ObjectIsString(), input); 91362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (String::Equals(type, factory()->undefined_string())) { 91462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value = graph()->NewNode( 91562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch common()->Select(MachineRepresentation::kTagged), 91662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch graph()->NewNode(simplified()->ReferenceEqual(), input, 91762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch jsgraph()->NullConstant()), 91862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch jsgraph()->FalseConstant(), 91962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch graph()->NewNode(simplified()->ObjectIsUndetectable(), input)); 92062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 92162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return NoChange(); 92262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 92362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (invert) { 92462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value = graph()->NewNode(simplified()->BooleanNot(), value); 92562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 92662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ReplaceWithValue(node, value); 92762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Replace(value); 928bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) { 931bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Reduction const reduction = ReduceJSEqualTypeOf(node, invert); 932f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (reduction.Changed()) return reduction; 933bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSBinopReduction r(this, node); 935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 93662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (r.BothInputsAre(Type::UniqueName())) { 93762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 93862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 93962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (r.IsInternalizedStringCompareOperation()) { 94062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch r.CheckInputsToInternalizedString(); 94162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 94262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.BothInputsAre(Type::String())) { 944bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return r.ChangeToPureOperator(simplified()->StringEqual(), invert); 945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (r.BothInputsAre(Type::Boolean())) { 947f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.BothInputsAre(Type::Receiver())) { 950f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (r.OneInputIs(Type::Undetectable())) { 9533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch RelaxEffectsAndControls(node); 9543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch node->RemoveInput(r.LeftInputIs(Type::Undetectable()) ? 0 : 1); 9553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch node->TrimInputCount(1); 9563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch NodeProperties::ChangeOp(node, simplified()->ObjectIsUndetectable()); 957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (invert) { 958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Insert an boolean not to invert the value. 959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* value = graph()->NewNode(simplified()->BooleanNot(), node); 960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceUses(value); 961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Note: ReplaceUses() smashes all uses, so smash it back here. 962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value->ReplaceInput(0, node); 963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Replace(value); 964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 967f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 968f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NumberOperationHint hint; 969f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (r.BothInputsAre(Type::Signed32()) || 970f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.BothInputsAre(Type::Unsigned32())) { 971f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); 972f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (r.GetCompareNumberOperationHint(&hint)) { 973f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToSpeculativeOperator( 974f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean()); 975f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (r.BothInputsAre(Type::Number())) { 976f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); 97762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (r.IsReceiverCompareOperation()) { 97862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch r.CheckInputsToReceiver(); 97962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 98062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (r.IsStringCompareOperation()) { 98162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch r.CheckInputsToString(); 98262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return r.ChangeToPureOperator(simplified()->StringEqual(), invert); 983f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) { 988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSBinopReduction r(this, node); 989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.left() == r.right()) { 990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // x === x is always true if x != NaN 991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!r.left_type()->Maybe(Type::NaN())) { 992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* replacement = jsgraph()->BooleanConstant(!invert); 993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReplaceWithValue(node, replacement); 994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Replace(replacement); 995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 99762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (r.OneInputCannotBe(Type::NumberOrString())) { 99813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // For values with canonical representation (i.e. neither String, nor 99962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Number) an empty type intersection means the values cannot be strictly 100062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // equal. 1001958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!r.left_type()->Maybe(r.right_type())) { 1002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* replacement = jsgraph()->BooleanConstant(invert); 1003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReplaceWithValue(node, replacement); 1004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Replace(replacement); 1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1007f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1008bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Reduction const reduction = ReduceJSEqualTypeOf(node, invert); 1009f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (reduction.Changed()) return reduction; 1010f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 101162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (r.BothInputsAre(Type::Unique())) { 1012f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 101462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (r.OneInputIs(pointer_comparable_type_)) { 1015f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 101762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (r.IsInternalizedStringCompareOperation()) { 101862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch r.CheckInputsToInternalizedString(); 1019f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.BothInputsAre(Type::String())) { 1022bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return r.ChangeToPureOperator(simplified()->StringEqual(), invert); 1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1024f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1025f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NumberOperationHint hint; 1026f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (r.BothInputsAre(Type::Signed32()) || 1027f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch r.BothInputsAre(Type::Unsigned32())) { 1028f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); 1029f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (r.GetCompareNumberOperationHint(&hint)) { 1030f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return r.ChangeToSpeculativeOperator( 1031f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean()); 1032f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (r.BothInputsAre(Type::Number())) { 1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); 103462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (r.IsReceiverCompareOperation()) { 103562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // For strict equality, it's enough to know that one input is a Receiver, 103662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // as a strict equality comparison with a Receiver can only yield true if 103762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // both sides refer to the same Receiver than. 103862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch r.CheckLeftInputToReceiver(); 103962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 104062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (r.IsStringCompareOperation()) { 104162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch r.CheckInputsToString(); 104262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return r.ChangeToPureOperator(simplified()->StringEqual(), invert); 1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1047958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierReduction JSTypedLowering::ReduceJSToBoolean(Node* node) { 1048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* const input = node->InputAt(0); 1049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* const input_type = NodeProperties::GetType(input); 1050958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (input_type->Is(Type::Boolean())) { 1051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // JSToBoolean(x:boolean) => x 1052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Replace(input); 1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (input_type->Is(Type::OrderedNumber())) { 1054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0)) 1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input, 1056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->ZeroConstant())); 1057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->TrimInputCount(1); 1058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp(node, simplified()->BooleanNot()); 1059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 1060f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (input_type->Is(Type::Number())) { 1061f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // JSToBoolean(x:number) => NumberToBoolean(x) 1062f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->TrimInputCount(1); 1063f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch NodeProperties::ChangeOp(node, simplified()->NumberToBoolean()); 1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 106562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (input_type->Is(Type::DetectableReceiverOrNull())) { 106662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // JSToBoolean(x:detectable receiver \/ null) 106762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // => BooleanNot(ReferenceEqual(x,#null)) 106862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node->ReplaceInput(0, graph()->NewNode(simplified()->ReferenceEqual(), 106962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch input, jsgraph()->NullConstant())); 107062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node->TrimInputCount(1); 107162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch NodeProperties::ChangeOp(node, simplified()->BooleanNot()); 107262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Changed(node); 107362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (input_type->Is(Type::ReceiverOrNullOrUndefined())) { 107462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // JSToBoolean(x:receiver \/ null \/ undefined) 107562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // => BooleanNot(ObjectIsUndetectable(x)) 107662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node->ReplaceInput( 107762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 0, graph()->NewNode(simplified()->ObjectIsUndetectable(), input)); 107862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node->TrimInputCount(1); 107962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch NodeProperties::ChangeOp(node, simplified()->BooleanNot()); 108062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Changed(node); 108162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (input_type->Is(Type::String())) { 108262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // JSToBoolean(x:string) => BooleanNot(ReferenceEqual(x,"")) 108362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node->ReplaceInput(0, 108462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch graph()->NewNode(simplified()->ReferenceEqual(), input, 108562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch jsgraph()->EmptyStringConstant())); 108662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node->TrimInputCount(1); 108762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch NodeProperties::ChangeOp(node, simplified()->BooleanNot()); 108862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Changed(node); 1089958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return NoChange(); 1091958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1092958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 10933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochReduction JSTypedLowering::ReduceJSToInteger(Node* node) { 10943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* const input = NodeProperties::GetValueInput(node, 0); 10953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Type* const input_type = NodeProperties::GetType(input); 10963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (input_type->Is(type_cache_.kIntegerOrMinusZero)) { 10973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // JSToInteger(x:integer) => x 10983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ReplaceWithValue(node, input); 10993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return Replace(input); 11003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 11013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return NoChange(); 11023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 11033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1104c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochReduction JSTypedLowering::ReduceJSToName(Node* node) { 1105c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* const input = NodeProperties::GetValueInput(node, 0); 1106c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Type* const input_type = NodeProperties::GetType(input); 1107c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (input_type->Is(Type::Name())) { 1108c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // JSToName(x:name) => x 1109c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ReplaceWithValue(node, input); 1110c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Replace(input); 1111c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1112c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return NoChange(); 1113c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 1114c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 11153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochReduction JSTypedLowering::ReduceJSToLength(Node* node) { 11163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* input = NodeProperties::GetValueInput(node, 0); 11173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Type* input_type = NodeProperties::GetType(input); 11183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (input_type->Is(type_cache_.kIntegerOrMinusZero)) { 11193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (input_type->Max() <= 0.0) { 11203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch input = jsgraph()->ZeroConstant(); 11213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else if (input_type->Min() >= kMaxSafeInteger) { 11223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch input = jsgraph()->Constant(kMaxSafeInteger); 11233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 11243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (input_type->Min() <= 0.0) { 1125f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch input = graph()->NewNode(simplified()->NumberMax(), 1126f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch jsgraph()->ZeroConstant(), input); 11273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 11283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (input_type->Max() > kMaxSafeInteger) { 1129f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch input = graph()->NewNode(simplified()->NumberMin(), 1130f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch jsgraph()->Constant(kMaxSafeInteger), input); 11313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 11323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 11333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ReplaceWithValue(node, input); 11343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return Replace(input); 11353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 11363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return NoChange(); 11373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 1138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSToNumberInput(Node* input) { 1140109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Try constant-folding of JSToNumber with constant inputs. 1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* input_type = NodeProperties::GetType(input); 1142c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (input_type->Is(Type::String())) { 1143c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HeapObjectMatcher m(input); 1144c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (m.HasValue() && m.Value()->IsString()) { 1145c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Object> input_value = m.Value(); 1146109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Replace(jsgraph()->Constant( 1147109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch String::ToNumber(Handle<String>::cast(input_value)))); 1148c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1149c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1150c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (input_type->IsHeapConstant()) { 1151c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Object> input_value = input_type->AsHeapConstant()->Value(); 1152c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (input_value->IsOddball()) { 1153109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return Replace(jsgraph()->Constant( 1154109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Oddball::ToNumber(Handle<Oddball>::cast(input_value)))); 1155109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1156109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input_type->Is(Type::Number())) { 1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JSToNumber(x:number) => x 1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Changed(input); 1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input_type->Is(Type::Undefined())) { 1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JSToNumber(undefined) => #NaN 1163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Replace(jsgraph()->NaNConstant()); 1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input_type->Is(Type::Null())) { 1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JSToNumber(null) => #0 1167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Replace(jsgraph()->ZeroConstant()); 1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierReduction JSTypedLowering::ReduceJSToNumber(Node* node) { 1173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Try to reduce the input first. 1174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const input = node->InputAt(0); 1175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Reduction reduction = ReduceJSToNumberInput(input); 1176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (reduction.Changed()) { 1177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReplaceWithValue(node, reduction.replacement()); 1178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return reduction; 1179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* const input_type = NodeProperties::GetType(input); 1181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (input_type->Is(Type::PlainPrimitive())) { 118213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RelaxEffectsAndControls(node); 118313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch node->TrimInputCount(1); 118413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch NodeProperties::ChangeOp(node, simplified()->PlainPrimitiveToNumber()); 118513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Changed(node); 1186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return NoChange(); 1188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSToStringInput(Node* input) { 1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input->opcode() == IrOpcode::kJSToString) { 1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Recursively try to reduce the input first. 1193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Reduction result = ReduceJSToString(input); 1194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (result.Changed()) return result; 1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Changed(input); // JSToString(JSToString(x)) => JSToString(x) 1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* input_type = NodeProperties::GetType(input); 1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input_type->Is(Type::String())) { 1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Changed(input); // JSToString(x:string) => x 1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (input_type->Is(Type::Boolean())) { 1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Replace(graph()->NewNode( 1203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch common()->Select(MachineRepresentation::kTagged), input, 1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->HeapConstant(factory()->true_string()), 1205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->HeapConstant(factory()->false_string()))); 1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input_type->Is(Type::Undefined())) { 1208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Replace(jsgraph()->HeapConstant(factory()->undefined_string())); 1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input_type->Is(Type::Null())) { 1211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Replace(jsgraph()->HeapConstant(factory()->null_string())); 1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(turbofan): js-typed-lowering of ToString(x:number) 1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierReduction JSTypedLowering::ReduceJSToString(Node* node) { 1218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Try to reduce the input first. 1219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const input = node->InputAt(0); 1220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Reduction reduction = ReduceJSToStringInput(input); 1221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (reduction.Changed()) { 1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReplaceWithValue(node, reduction.replacement()); 1223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return reduction; 1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochReduction JSTypedLowering::ReduceJSToObject(Node* node) { 1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(IrOpcode::kJSToObject, node->opcode()); 1230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* receiver = NodeProperties::GetValueInput(node, 0); 1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* receiver_type = NodeProperties::GetType(receiver); 1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* context = NodeProperties::GetContextInput(node); 1233f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* frame_state = NodeProperties::GetFrameStateInput(node); 1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 1236f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (receiver_type->Is(Type::Receiver())) { 1237f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReplaceWithValue(node, receiver, effect, control); 1238f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Replace(receiver); 1239f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1241f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // TODO(bmeurer/mstarzinger): Add support for lowering inside try blocks. 1242f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (receiver_type->Maybe(Type::NullOrUndefined()) && 1243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::IsExceptionalCall(node)) { 1244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // ToObject throws for null or undefined inputs. 1245f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return NoChange(); 1246f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Check whether {receiver} is a spec object. 1249f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* check = graph()->NewNode(simplified()->ObjectIsReceiver(), receiver); 1250f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* branch = 1251f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); 1252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1253f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 1254f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* etrue = effect; 1255f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* rtrue = receiver; 1256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1257f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 1258f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* efalse = effect; 1259f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* rfalse; 1260f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 1261f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Convert {receiver} using the ToObjectStub. 1262f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Callable callable = CodeFactory::ToObject(isolate()); 1263f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( 1264f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate(), graph()->zone(), callable.descriptor(), 0, 1265f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor::kNeedsFrameState, node->op()->properties()); 1266f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch rfalse = efalse = graph()->NewNode( 1267f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch common()->Call(desc), jsgraph()->HeapConstant(callable.code()), 1268f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch receiver, context, frame_state, efalse, if_false); 1269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if_false = graph()->NewNode(common()->IfSuccess(), rfalse); 1270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1272f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch control = graph()->NewNode(common()->Merge(2), if_true, if_false); 1273f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); 1274f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1275f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Morph the {node} into an appropriate Phi. 1276f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReplaceWithValue(node, node, effect, control); 1277f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(0, rtrue); 1278f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(1, rfalse); 1279f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(2, control); 1280f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->TrimInputCount(3); 1281f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ChangeOp(node, 1282f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch common()->Phi(MachineRepresentation::kTagged, 2)); 1283f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Changed(node); 1284f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochReduction JSTypedLowering::ReduceJSLoadNamed(Node* node) { 1287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode()); 1288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* receiver = NodeProperties::GetValueInput(node, 0); 1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* receiver_type = NodeProperties::GetType(receiver); 1290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 1292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> name = NamedAccessOf(node->op()).name(); 1293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Optimize "length" property of strings. 1294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (name.is_identical_to(factory()->length_string()) && 1295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver_type->Is(Type::String())) { 1296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* value = effect = graph()->NewNode( 1297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->LoadField(AccessBuilder::ForStringLength()), receiver, 1298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch effect, control); 1299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReplaceWithValue(node, value, effect); 1300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Replace(value); 1301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return NoChange(); 1303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSLoadProperty(Node* node) { 1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* key = NodeProperties::GetValueInput(node, 1); 1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* base = NodeProperties::GetValueInput(node, 0); 1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* key_type = NodeProperties::GetType(key); 1309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HeapObjectMatcher mbase(base); 1310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mbase.HasValue() && mbase.Value()->IsJSTypedArray()) { 1311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSTypedArray> const array = 1312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSTypedArray>::cast(mbase.Value()); 1313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!array->GetBuffer()->was_neutered()) { 1314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch array->GetBuffer()->set_is_neuterable(false); 1315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BufferAccess const access(array->type()); 1316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t const k = 1317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementSizeLog2Of(access.machine_type().representation()); 1318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double const byte_length = array->byte_length()->Number(); 1319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_LT(k, arraysize(shifted_int32_ranges_)); 1320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) { 1321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // JSLoadProperty(typed-array, int32) 1322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedTypedArrayBase> elements = 1323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedTypedArrayBase>::cast(handle(array->elements())); 1324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* buffer = jsgraph()->PointerConstant(elements->external_pointer()); 1325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* length = jsgraph()->Constant(byte_length); 1326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 1328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if we can avoid the bounds check. 1329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (key_type->Min() >= 0 && key_type->Max() < array->length_value()) { 1330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* load = graph()->NewNode( 1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->LoadElement( 1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AccessBuilder::ForTypedArrayElement(array->type(), true)), 1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch buffer, key, effect, control); 1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReplaceWithValue(node, load, load); 1335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Replace(load); 1336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compute byte offset. 1338f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* offset = 1339f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (k == 0) ? key : graph()->NewNode( 1340f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch simplified()->NumberShiftLeft(), key, 1341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch jsgraph()->Constant(static_cast<double>(k))); 1342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* load = graph()->NewNode(simplified()->LoadBuffer(access), buffer, 1343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch offset, length, effect, control); 1344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReplaceWithValue(node, load, load); 1345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Replace(load); 1346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSStoreProperty(Node* node) { 1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* key = NodeProperties::GetValueInput(node, 1); 1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* base = NodeProperties::GetValueInput(node, 0); 1355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = NodeProperties::GetValueInput(node, 2); 1356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* key_type = NodeProperties::GetType(key); 1357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* value_type = NodeProperties::GetType(value); 135862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 135962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!value_type->Is(Type::PlainPrimitive())) return NoChange(); 136062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 1361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HeapObjectMatcher mbase(base); 1362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mbase.HasValue() && mbase.Value()->IsJSTypedArray()) { 1363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSTypedArray> const array = 1364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSTypedArray>::cast(mbase.Value()); 1365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!array->GetBuffer()->was_neutered()) { 1366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch array->GetBuffer()->set_is_neuterable(false); 1367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BufferAccess const access(array->type()); 1368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t const k = 1369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementSizeLog2Of(access.machine_type().representation()); 1370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double const byte_length = array->byte_length()->Number(); 1371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK_LT(k, arraysize(shifted_int32_ranges_)); 1372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (access.external_array_type() != kExternalUint8ClampedArray && 1373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) { 1374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // JSLoadProperty(typed-array, int32) 1375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedTypedArrayBase> elements = 1376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedTypedArrayBase>::cast(handle(array->elements())); 1377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* buffer = jsgraph()->PointerConstant(elements->external_pointer()); 1378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* length = jsgraph()->Constant(byte_length); 1379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 1381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Convert to a number first. 138213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!value_type->Is(Type::Number())) { 1383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Reduction number_reduction = ReduceJSToNumberInput(value); 1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (number_reduction.Changed()) { 1385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value = number_reduction.replacement(); 1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 138762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value = 138862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch graph()->NewNode(simplified()->PlainPrimitiveToNumber(), value); 1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if we can avoid the bounds check. 1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (key_type->Min() >= 0 && key_type->Max() < array->length_value()) { 1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelaxControls(node); 1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(0, buffer); 1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(key, node->InputAt(1)); 1396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(2, value); 1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(3, effect); 1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(4, control); 1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->TrimInputCount(5); 1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp( 1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node, 1402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->StoreElement( 1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AccessBuilder::ForTypedArrayElement(array->type(), true))); 1404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compute byte offset. 1407f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* offset = 1408f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (k == 0) ? key : graph()->NewNode( 1409f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch simplified()->NumberShiftLeft(), key, 1410f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch jsgraph()->Constant(static_cast<double>(k))); 1411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Turn into a StoreBuffer operation. 1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelaxControls(node); 1413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node->ReplaceInput(0, buffer); 1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(1, offset); 1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(2, length); 1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(3, value); 1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(4, effect); 1418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(5, control); 1419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->TrimInputCount(6); 1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp(node, simplified()->StoreBuffer(access)); 1421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Changed(node); 1422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1428f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochReduction JSTypedLowering::ReduceJSOrdinaryHasInstance(Node* node) { 1429f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK_EQ(IrOpcode::kJSOrdinaryHasInstance, node->opcode()); 1430f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* constructor = NodeProperties::GetValueInput(node, 0); 1431f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Type* constructor_type = NodeProperties::GetType(constructor); 1432f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* object = NodeProperties::GetValueInput(node, 1); 143362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Type* object_type = NodeProperties::GetType(object); 1434f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* context = NodeProperties::GetContextInput(node); 1435f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* frame_state = NodeProperties::GetFrameStateInput(node); 1436f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1437f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 1438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 143962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Check if the {constructor} cannot be callable. 144062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // See ES6 section 7.3.19 OrdinaryHasInstance ( C, O ) step 1. 144162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!constructor_type->Maybe(Type::Callable())) { 144262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* value = jsgraph()->FalseConstant(); 144362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ReplaceWithValue(node, value, effect, control); 144462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Replace(value); 144562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 144662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 144762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // If the {constructor} cannot be a JSBoundFunction and then {object} 144862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // cannot be a JSReceiver, then this can be constant-folded to false. 144962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // See ES6 section 7.3.19 OrdinaryHasInstance ( C, O ) step 2 and 3. 145062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!object_type->Maybe(Type::Receiver()) && 145162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch !constructor_type->Maybe(Type::BoundFunction())) { 145262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* value = jsgraph()->FalseConstant(); 145362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ReplaceWithValue(node, value, effect, control); 145462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Replace(value); 145562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 145662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 1457f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if the {constructor} is a (known) JSFunction. 1458c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!constructor_type->IsHeapConstant() || 1459c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch !constructor_type->AsHeapConstant()->Value()->IsJSFunction()) { 1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return NoChange(); 1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSFunction> function = 1463c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<JSFunction>::cast(constructor_type->AsHeapConstant()->Value()); 1464f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1465f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if the {function} already has an initial map (i.e. the 1466f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // {function} has been used as a constructor at least once). 1467f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!function->has_initial_map()) return NoChange(); 1468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1469f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if the {function}s "prototype" is a JSReceiver. 1470f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!function->prototype()->IsJSReceiver()) return NoChange(); 1471bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1472f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Install a code dependency on the {function}s initial map. 1473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> initial_map(function->initial_map(), isolate()); 1474bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch dependencies()->AssumeInitialMapCantChange(initial_map); 1475f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* prototype = 1477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->Constant(handle(initial_map->prototype(), isolate())); 1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1479f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), object); 1480f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* branch0 = 1481f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(common()->Branch(BranchHint::kFalse), check0, control); 1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1483f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 1484f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* etrue0 = effect; 1485f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* vtrue0 = jsgraph()->FalseConstant(); 1486f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1487f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch control = graph()->NewNode(common()->IfFalse(), branch0); 1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Loop through the {object}s prototype chain looking for the {prototype}. 1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* loop = control = graph()->NewNode(common()->Loop(2), control, control); 1491f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* eloop = effect = 1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(common()->EffectPhi(2), effect, effect, loop); 1493f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* vloop = object = graph()->NewNode( 1494f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch common()->Phi(MachineRepresentation::kTagged, 2), object, object, loop); 1495f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // TODO(jarin): This is a very ugly hack to work-around the super-smart 1496f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // implicit typing of the Phi, which goes completely nuts if the {object} 1497f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // is for example a HeapConstant. 1498f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch NodeProperties::SetType(vloop, Type::NonInternal()); 1499f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1500f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Load the {object} map and instance type. 1501f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* object_map = effect = 1502f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), object, 1503f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect, control); 1504f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* object_instance_type = effect = graph()->NewNode( 1505f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->LoadField(AccessBuilder::ForMapInstanceType()), object_map, 1506f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect, control); 1507f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1508f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if the {object} is a special receiver, because for special 1509f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // receivers, i.e. proxies or API objects that need access checks, 1510f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // we have to use the %HasInPrototypeChain runtime function instead. 1511f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* check1 = graph()->NewNode( 1512f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->NumberLessThanOrEqual(), object_instance_type, 1513f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch jsgraph()->Constant(LAST_SPECIAL_RECEIVER_TYPE)); 1514f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* branch1 = 1515f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, control); 1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1517f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch control = graph()->NewNode(common()->IfFalse(), branch1); 1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1519f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); 1520f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* etrue1 = effect; 1521f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* vtrue1; 1522f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1523f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if the {object} is not a receiver at all. 1524f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* check10 = 1525f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(simplified()->NumberLessThan(), object_instance_type, 1526f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch jsgraph()->Constant(FIRST_JS_RECEIVER_TYPE)); 1527f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* branch10 = 1528f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->NewNode(common()->Branch(BranchHint::kTrue), check10, if_true1); 1529f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1530f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // A primitive value cannot match the {prototype} we're looking for. 1531f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if_true1 = graph()->NewNode(common()->IfTrue(), branch10); 1532f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vtrue1 = jsgraph()->FalseConstant(); 1533f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1534f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch10); 1535f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* efalse1 = etrue1; 1536f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* vfalse1; 1537f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch { 1538f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Slow path, need to call the %HasInPrototypeChain runtime function. 1539f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vfalse1 = efalse1 = graph()->NewNode( 1540f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch javascript()->CallRuntime(Runtime::kHasInPrototypeChain), object, 1541f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch prototype, context, frame_state, efalse1, if_false1); 1542f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if_false1 = graph()->NewNode(common()->IfSuccess(), vfalse1); 1543f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1544f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Replace any potential IfException on {node} to catch exceptions 1545f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // from this %HasInPrototypeChain runtime call instead. 1546f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch for (Edge edge : node->use_edges()) { 1547f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (edge.from()->opcode() == IrOpcode::kIfException) { 1548f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch edge.UpdateTo(vfalse1); 1549f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Revisit(edge.from()); 1550f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1551f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1552f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1554f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Load the {object} prototype. 1555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* object_prototype = effect = graph()->NewNode( 1556f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch simplified()->LoadField(AccessBuilder::ForMapPrototype()), object_map, 1557f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect, control); 1558f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1559f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if we reached the end of {object}s prototype chain. 1560f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* check2 = graph()->NewNode(simplified()->ReferenceEqual(), 1561f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch object_prototype, jsgraph()->NullConstant()); 1562f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* branch2 = graph()->NewNode(common()->Branch(), check2, control); 1563f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1564f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); 1565f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* etrue2 = effect; 1566f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* vtrue2 = jsgraph()->FalseConstant(); 1567f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1568f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch control = graph()->NewNode(common()->IfFalse(), branch2); 1569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1570f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Check if we reached the {prototype}. 1571f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* check3 = graph()->NewNode(simplified()->ReferenceEqual(), 1572f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch object_prototype, prototype); 1573f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* branch3 = graph()->NewNode(common()->Branch(), check3, control); 1574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1575f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* if_true3 = graph()->NewNode(common()->IfTrue(), branch3); 1576f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* etrue3 = effect; 1577f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* vtrue3 = jsgraph()->TrueConstant(); 1578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1579f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch control = graph()->NewNode(common()->IfFalse(), branch3); 1580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1581f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Close the loop. 1582f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch vloop->ReplaceInput(1, object_prototype); 1583f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch eloop->ReplaceInput(1, effect); 1584f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch loop->ReplaceInput(1, control); 1585f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1586f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch control = graph()->NewNode(common()->Merge(5), if_true0, if_true1, if_true2, 1587f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if_true3, if_false1); 1588f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch effect = graph()->NewNode(common()->EffectPhi(5), etrue0, etrue1, etrue2, 1589f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch etrue3, efalse1, control); 1590f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1591f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Morph the {node} into an appropriate Phi. 1592f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ReplaceWithValue(node, node, effect, control); 1593f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->ReplaceInput(0, vtrue0); 1594f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->ReplaceInput(1, vtrue1); 1595f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->ReplaceInput(2, vtrue2); 1596f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->ReplaceInput(3, vtrue3); 1597f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->ReplaceInput(4, vfalse1); 1598f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->ReplaceInput(5, control); 1599f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->TrimInputCount(6); 1600f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch NodeProperties::ChangeOp(node, 1601f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch common()->Phi(MachineRepresentation::kTagged, 5)); 1602f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return Changed(node); 1603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1605958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierReduction JSTypedLowering::ReduceJSLoadContext(Node* node) { 1606958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode()); 1607958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ContextAccess const& access = ContextAccessOf(node->op()); 1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 160962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* context = NodeProperties::GetContextInput(node); 1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = graph()->start(); 1611958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (size_t i = 0; i < access.depth(); ++i) { 161262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch context = effect = graph()->NewNode( 1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->LoadField( 1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)), 161562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch context, effect, control); 1616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 161762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node->ReplaceInput(0, context); 1618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node->ReplaceInput(1, effect); 161962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node->AppendInput(jsgraph()->zone(), control); 1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp( 1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node, 1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->LoadField(AccessBuilder::ForContextSlot(access.index()))); 1623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Changed(node); 1624958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1625958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1626958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierReduction JSTypedLowering::ReduceJSStoreContext(Node* node) { 1627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(IrOpcode::kJSStoreContext, node->opcode()); 1628958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ContextAccess const& access = ContextAccessOf(node->op()); 1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 163062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* context = NodeProperties::GetContextInput(node); 1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = graph()->start(); 163262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* value = NodeProperties::GetValueInput(node, 0); 1633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (size_t i = 0; i < access.depth(); ++i) { 163462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch context = effect = graph()->NewNode( 1635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->LoadField( 1636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)), 163762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch context, effect, control); 1638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 163962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node->ReplaceInput(0, context); 164062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node->ReplaceInput(1, value); 1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(2, effect); 1642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp( 1643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node, 1644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->StoreField(AccessBuilder::ForContextSlot(access.index()))); 1645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 1646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1648c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochReduction JSTypedLowering::ReduceJSLoadModule(Node* node) { 1649c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(IrOpcode::kJSLoadModule, node->opcode()); 1650c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1651c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* control = NodeProperties::GetControlInput(node); 1652c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1653c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t cell_index = OpParameter<int32_t>(node); 1654c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* module = NodeProperties::GetValueInput(node, 0); 1655c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1656c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* array; 1657c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int index; 1658c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (ModuleDescriptor::GetCellIndexKind(cell_index) == 1659c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ModuleDescriptor::kExport) { 1660c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch array = effect = graph()->NewNode( 1661c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch simplified()->LoadField(AccessBuilder::ForModuleRegularExports()), 1662c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch module, effect, control); 1663c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch index = cell_index - 1; 1664c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 1665c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index), 1666c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ModuleDescriptor::kImport); 1667c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch array = effect = graph()->NewNode( 1668c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch simplified()->LoadField(AccessBuilder::ForModuleRegularImports()), 1669c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch module, effect, control); 1670c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch index = -cell_index - 1; 1671c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1672c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1673c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* cell = effect = graph()->NewNode( 1674c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch simplified()->LoadField(AccessBuilder::ForFixedArraySlot(index)), array, 1675c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch effect, control); 1676c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1677c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* value = effect = 1678c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch graph()->NewNode(simplified()->LoadField(AccessBuilder::ForCellValue()), 1679c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch cell, effect, control); 1680c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1681c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ReplaceWithValue(node, value, effect, control); 1682c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Changed(value); 1683c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 1684c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1685c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochReduction JSTypedLowering::ReduceJSStoreModule(Node* node) { 1686c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(IrOpcode::kJSStoreModule, node->opcode()); 1687c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1688c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* control = NodeProperties::GetControlInput(node); 1689c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1690c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t cell_index = OpParameter<int32_t>(node); 1691c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* module = NodeProperties::GetValueInput(node, 0); 1692c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* value = NodeProperties::GetValueInput(node, 1); 1693c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1694c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* array; 1695c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int index; 1696c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (ModuleDescriptor::GetCellIndexKind(cell_index) == 1697c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ModuleDescriptor::kExport) { 1698c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch array = effect = graph()->NewNode( 1699c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch simplified()->LoadField(AccessBuilder::ForModuleRegularExports()), 1700c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch module, effect, control); 1701c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch index = cell_index - 1; 1702c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 1703c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index), 1704c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ModuleDescriptor::kImport); 1705c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch array = effect = graph()->NewNode( 1706c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch simplified()->LoadField(AccessBuilder::ForModuleRegularImports()), 1707c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch module, effect, control); 1708c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch index = -cell_index - 1; 1709c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1710c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1711c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* cell = effect = graph()->NewNode( 1712c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch simplified()->LoadField(AccessBuilder::ForFixedArraySlot(index)), array, 1713c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch effect, control); 1714c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1715c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch effect = 1716c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch graph()->NewNode(simplified()->StoreField(AccessBuilder::ForCellValue()), 1717c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch cell, value, effect, control); 1718c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1719c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ReplaceWithValue(node, effect, effect, control); 1720c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Changed(value); 1721c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 1722c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochReduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) { 1724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(IrOpcode::kJSConvertReceiver, node->opcode()); 1725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConvertReceiverMode mode = ConvertReceiverModeOf(node->op()); 1726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* receiver = NodeProperties::GetValueInput(node, 0); 1727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* receiver_type = NodeProperties::GetType(receiver); 1728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* context = NodeProperties::GetContextInput(node); 1729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* context_type = NodeProperties::GetType(context); 1730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 1732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Check if {receiver} is known to be a receiver. 1734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (receiver_type->Is(Type::Receiver())) { 1735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReplaceWithValue(node, receiver, effect, control); 1736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Replace(receiver); 1737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1738f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1739f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // If the {receiver} is known to be null or undefined, we can just replace it 1740f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // with the global proxy unconditionally. 1741f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (receiver_type->Is(Type::NullOrUndefined()) || 1742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch mode == ConvertReceiverMode::kNullOrUndefined) { 1743c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (context_type->IsHeapConstant()) { 1744f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> global_proxy( 1745c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Context>::cast(context_type->AsHeapConstant()->Value()) 1746f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ->global_proxy(), 1747f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate()); 1748f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch receiver = jsgraph()->Constant(global_proxy); 1749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1750f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* native_context = effect = graph()->NewNode( 1751f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true), 175262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch context, effect); 1753f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch receiver = effect = graph()->NewNode( 1754f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch javascript()->LoadContext(0, Context::GLOBAL_PROXY_INDEX, true), 175562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch native_context, effect); 1756f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1757f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReplaceWithValue(node, receiver, effect, control); 1758f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Replace(receiver); 1759f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1761f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // If {receiver} cannot be null or undefined we can skip a few checks. 1762f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!receiver_type->Maybe(Type::NullOrUndefined()) || 1763f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch mode == ConvertReceiverMode::kNotNullOrUndefined) { 1764f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* check = graph()->NewNode(simplified()->ObjectIsReceiver(), receiver); 1765f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* branch = 1766f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); 1767f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1768f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 1769f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* etrue = effect; 1770f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* rtrue = receiver; 1771f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1772f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 1773f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* efalse = effect; 1774f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* rfalse; 1775f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 177662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Convert {receiver} using the ToObjectStub. The call does not require a 177762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // frame-state in this case, because neither null nor undefined is passed. 1778f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Callable callable = CodeFactory::ToObject(isolate()); 1779f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( 1780f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate(), graph()->zone(), callable.descriptor(), 0, 178162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CallDescriptor::kNoFlags, node->op()->properties()); 1782f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch rfalse = efalse = graph()->NewNode( 1783f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch common()->Call(desc), jsgraph()->HeapConstant(callable.code()), 178462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch receiver, context, efalse); 1785f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1786f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1787f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch control = graph()->NewNode(common()->Merge(2), if_true, if_false); 1788f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); 1789f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1790f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Morph the {node} into an appropriate Phi. 1791f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReplaceWithValue(node, node, effect, control); 1792f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(0, rtrue); 1793f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(1, rfalse); 1794f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(2, control); 1795f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->TrimInputCount(3); 1796f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ChangeOp(node, 1797f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch common()->Phi(MachineRepresentation::kTagged, 2)); 1798f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Changed(node); 1799f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1800f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Check if {receiver} is already a JSReceiver. 1802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* check0 = graph()->NewNode(simplified()->ObjectIsReceiver(), receiver); 1803f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* branch0 = 1804f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); 1805f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 1806f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); 1807f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1808f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Check {receiver} for undefined. 1809f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* check1 = graph()->NewNode(simplified()->ReferenceEqual(), receiver, 1810f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch jsgraph()->UndefinedConstant()); 1811f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* branch1 = 1812f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, if_false0); 1813f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); 1814f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); 1815f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1816f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Check {receiver} for null. 1817f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* check2 = graph()->NewNode(simplified()->ReferenceEqual(), receiver, 1818f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch jsgraph()->NullConstant()); 1819f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* branch2 = 1820f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->Branch(BranchHint::kFalse), check2, if_false1); 1821f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); 1822f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); 1823f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1824f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // We just use {receiver} directly. 1825f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_noop = if_true0; 1826f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* enoop = effect; 1827f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* rnoop = receiver; 1828f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1829f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Convert {receiver} using ToObject. 1830f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_convert = if_false2; 1831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* econvert = effect; 1832f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* rconvert; 1833f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 183462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Convert {receiver} using the ToObjectStub. The call does not require a 183562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // frame-state in this case, because neither null nor undefined is passed. 1836f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Callable callable = CodeFactory::ToObject(isolate()); 1837f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( 1838f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate(), graph()->zone(), callable.descriptor(), 0, 183962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CallDescriptor::kNoFlags, node->op()->properties()); 1840f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch rconvert = econvert = graph()->NewNode( 1841f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch common()->Call(desc), jsgraph()->HeapConstant(callable.code()), 184262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch receiver, context, econvert); 1843f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1845f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Replace {receiver} with global proxy of {context}. 1846f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* if_global = graph()->NewNode(common()->Merge(2), if_true1, if_true2); 1847f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* eglobal = effect; 1848f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* rglobal; 1849f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch { 1850c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (context_type->IsHeapConstant()) { 1851f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> global_proxy( 1852c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Context>::cast(context_type->AsHeapConstant()->Value()) 1853f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ->global_proxy(), 1854f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate()); 1855f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch rglobal = jsgraph()->Constant(global_proxy); 1856f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1857f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* native_context = eglobal = graph()->NewNode( 1858f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true), 185962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch context, eglobal); 1860f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch rglobal = eglobal = graph()->NewNode( 1861f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch javascript()->LoadContext(0, Context::GLOBAL_PROXY_INDEX, true), 186262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch native_context, eglobal); 1863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1865f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1866f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch control = 1867f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch graph()->NewNode(common()->Merge(3), if_noop, if_convert, if_global); 1868f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch effect = graph()->NewNode(common()->EffectPhi(3), enoop, econvert, eglobal, 1869f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch control); 1870f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Morph the {node} into an appropriate Phi. 1871f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReplaceWithValue(node, node, effect, control); 1872f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(0, rnoop); 1873f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(1, rconvert); 1874f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(2, rglobal); 1875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(3, control); 1876f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->TrimInputCount(4); 1877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ChangeOp(node, 1878f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch common()->Phi(MachineRepresentation::kTagged, 3)); 1879f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Changed(node); 1880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1882f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace { 1883f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1884f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid ReduceBuiltin(Isolate* isolate, JSGraph* jsgraph, Node* node, 1885f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int builtin_index, int arity, CallDescriptor::Flags flags) { 1886f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Patch {node} to a direct CEntryStub call. 1887f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // 1888f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // ----------- A r g u m e n t s ----------- 1889f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // -- 0: CEntryStub 1890f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // --- Stack args --- 1891f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // -- 1: receiver 1892f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // -- [2, 2 + n[: the n actual arguments passed to the builtin 1893f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // -- 2 + n: argc, including the receiver and implicit args (Smi) 1894f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // -- 2 + n + 1: target 1895f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // -- 2 + n + 2: new_target 1896f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // --- Register args --- 1897f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // -- 2 + n + 3: the C entry point 1898f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // -- 2 + n + 4: argc (Int32) 1899f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // ----------------------------------- 1900f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1901f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // The logic contained here is mirrored in Builtins::Generate_Adaptor. 1902f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Keep these in sync. 1903f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 190462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const bool is_construct = (node->opcode() == IrOpcode::kJSConstruct); 1905f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1906f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(Builtins::HasCppImplementation(builtin_index)); 1907c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(0, flags & CallDescriptor::kSupportsTailCalls); 1908f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1909f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* target = NodeProperties::GetValueInput(node, 0); 1910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* new_target = is_construct 1911f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ? NodeProperties::GetValueInput(node, arity + 1) 1912f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : jsgraph->UndefinedConstant(); 1913f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1914f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // API and CPP builtins are implemented in C++, and we can inline both. 1915f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // CPP builtins create a builtin exit frame, API builtins don't. 1916f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const bool has_builtin_exit_frame = Builtins::IsCpp(builtin_index); 1917f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1918f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* stub = jsgraph->CEntryStubConstant(1, kDontSaveFPRegs, kArgvOnStack, 1919f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch has_builtin_exit_frame); 1920f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->ReplaceInput(0, stub); 1921f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1922f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Zone* zone = jsgraph->zone(); 1923f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (is_construct) { 1924f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Unify representations between construct and call nodes. 1925f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Remove new target and add receiver as a stack parameter. 1926f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* receiver = jsgraph->UndefinedConstant(); 1927f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->RemoveInput(arity + 1); 1928f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InsertInput(zone, 1, receiver); 1929f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1930f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1931f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const int argc = arity + BuiltinArguments::kNumExtraArgsWithReceiver; 1932c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* argc_node = jsgraph->Constant(argc); 1933f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1934f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch static const int kStubAndReceiver = 2; 1935f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int cursor = arity + kStubAndReceiver; 1936f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->InsertInput(zone, cursor++, argc_node); 1937f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->InsertInput(zone, cursor++, target); 1938f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->InsertInput(zone, cursor++, new_target); 1939f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1940f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Address entry = Builtins::CppEntryOf(builtin_index); 1941f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ExternalReference entry_ref(ExternalReference(entry, isolate)); 1942f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* entry_node = jsgraph->ExternalConstant(entry_ref); 1943f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1944f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->InsertInput(zone, cursor++, entry_node); 1945f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->InsertInput(zone, cursor++, argc_node); 1946f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1947f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static const int kReturnCount = 1; 1948f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const char* debug_name = Builtins::name(builtin_index); 1949f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Operator::Properties properties = node->op()->properties(); 1950f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor* desc = Linkage::GetCEntryStubCallDescriptor( 1951f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch zone, kReturnCount, argc, debug_name, properties, flags); 1952f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1953f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ChangeOp(node, jsgraph->common()->Call(desc)); 1954f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 1955f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1956f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool NeedsArgumentAdaptorFrame(Handle<SharedFunctionInfo> shared, int arity) { 1957f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch static const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; 1958f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const int num_decl_parms = shared->internal_formal_parameter_count(); 1959f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return (num_decl_parms != arity && num_decl_parms != sentinel); 1960f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 1961f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1962f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} // namespace 1963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 196462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceJSConstruct(Node* node) { 196562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(IrOpcode::kJSConstruct, node->opcode()); 196662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ConstructParameters const& p = ConstructParametersOf(node->op()); 1967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_LE(2u, p.arity()); 1968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int const arity = static_cast<int>(p.arity() - 2); 1969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* target = NodeProperties::GetValueInput(node, 0); 1970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* target_type = NodeProperties::GetType(target); 1971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* new_target = NodeProperties::GetValueInput(node, arity + 1); 1972f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* effect = NodeProperties::GetEffectInput(node); 1973f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* control = NodeProperties::GetControlInput(node); 1974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if {target} is a known JSFunction. 1976c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (target_type->IsHeapConstant() && 1977c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch target_type->AsHeapConstant()->Value()->IsJSFunction()) { 1978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSFunction> function = 1979c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<JSFunction>::cast(target_type->AsHeapConstant()->Value()); 1980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SharedFunctionInfo> shared(function->shared(), isolate()); 1981f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const int builtin_index = shared->construct_stub()->builtin_index(); 1982f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const bool is_builtin = (builtin_index != -1); 1983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1984f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; 1985f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1986f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (is_builtin && Builtins::HasCppImplementation(builtin_index) && 1987f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch !NeedsArgumentAdaptorFrame(shared, arity)) { 1988f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Patch {node} to a direct CEntryStub call. 1989f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1990f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Load the context from the {target}. 1991f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* context = effect = graph()->NewNode( 1992f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch simplified()->LoadField(AccessBuilder::ForJSFunctionContext()), 1993f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch target, effect, control); 1994f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ReplaceContextInput(node, context); 1995f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1996f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Update the effect dependency for the {node}. 1997f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ReplaceEffectInput(node, effect); 1998f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1999f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ReduceBuiltin(isolate(), jsgraph(), node, builtin_index, arity, flags); 2000f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2001f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Patch {node} to an indirect call via the {function}s construct stub. 2002f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Callable callable(handle(shared->construct_stub(), isolate()), 2003f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ConstructStubDescriptor(isolate())); 2004f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->RemoveInput(arity + 1); 2005f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InsertInput(graph()->zone(), 0, 2006f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch jsgraph()->HeapConstant(callable.code())); 2007f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InsertInput(graph()->zone(), 2, new_target); 2008c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(arity)); 2009f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); 2010f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InsertInput(graph()->zone(), 5, jsgraph()->UndefinedConstant()); 2011f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NodeProperties::ChangeOp( 2012f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node, common()->Call(Linkage::GetStubCallDescriptor( 2013f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate(), graph()->zone(), callable.descriptor(), 2014f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1 + arity, flags))); 2015f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 2017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if {target} is a JSFunction. 2020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (target_type->Is(Type::Function())) { 2021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Patch {node} to an indirect call via the ConstructFunction builtin. 2022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Callable callable = CodeFactory::ConstructFunction(isolate()); 2023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->RemoveInput(arity + 1); 2024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 0, 2025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->HeapConstant(callable.code())); 2026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 2, new_target); 2027c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(arity)); 2028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); 2029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp( 2030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node, common()->Call(Linkage::GetStubCallDescriptor( 2031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate(), graph()->zone(), callable.descriptor(), 1 + arity, 2032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor::kNeedsFrameState))); 2033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return NoChange(); 2037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 203962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceJSCallForwardVarargs(Node* node) { 204062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(IrOpcode::kJSCallForwardVarargs, node->opcode()); 204162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CallForwardVarargsParameters p = CallForwardVarargsParametersOf(node->op()); 204262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* target = NodeProperties::GetValueInput(node, 0); 204362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Type* target_type = NodeProperties::GetType(target); 204462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 204562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Check if {target} is a JSFunction. 204662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (target_type->Is(Type::Function())) { 204762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Compute flags for the call. 204862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; 204962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (p.tail_call_mode() == TailCallMode::kAllow) { 205062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch flags |= CallDescriptor::kSupportsTailCalls; 205162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 205262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 205362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Patch {node} to an indirect call via CallFunctionForwardVarargs. 205462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Callable callable = CodeFactory::CallFunctionForwardVarargs(isolate()); 205562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node->InsertInput(graph()->zone(), 0, 205662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch jsgraph()->HeapConstant(callable.code())); 205762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node->InsertInput(graph()->zone(), 2, jsgraph()->Constant(p.start_index())); 205862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch NodeProperties::ChangeOp( 205962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node, 206062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch common()->Call(Linkage::GetStubCallDescriptor( 206162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate(), graph()->zone(), callable.descriptor(), 1, flags))); 206262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Changed(node); 206362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 206462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 206562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return NoChange(); 206662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 2067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 206862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceJSCall(Node* node) { 206962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); 207062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CallParameters const& p = CallParametersOf(node->op()); 2071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int const arity = static_cast<int>(p.arity() - 2); 2072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConvertReceiverMode convert_mode = p.convert_mode(); 2073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* target = NodeProperties::GetValueInput(node, 0); 2074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* target_type = NodeProperties::GetType(target); 2075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* receiver = NodeProperties::GetValueInput(node, 1); 2076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Type* receiver_type = NodeProperties::GetType(receiver); 2077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 2078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 2079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Try to infer receiver {convert_mode} from {receiver} type. 2081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (receiver_type->Is(Type::NullOrUndefined())) { 2082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch convert_mode = ConvertReceiverMode::kNullOrUndefined; 2083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (!receiver_type->Maybe(Type::NullOrUndefined())) { 2084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if {target} is a known JSFunction. 2088c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (target_type->IsHeapConstant() && 2089c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch target_type->AsHeapConstant()->Value()->IsJSFunction()) { 2090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSFunction> function = 2091c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<JSFunction>::cast(target_type->AsHeapConstant()->Value()); 2092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SharedFunctionInfo> shared(function->shared(), isolate()); 2093f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const int builtin_index = shared->code()->builtin_index(); 2094f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const bool is_builtin = (builtin_index != -1); 2095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Class constructors are callable, but [[Call]] will raise an exception. 2097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList ). 2098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsClassConstructor(shared->kind())) return NoChange(); 2099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Load the context from the {target}. 2101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* context = effect = graph()->NewNode( 2102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->LoadField(AccessBuilder::ForJSFunctionContext()), target, 2103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch effect, control); 2104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ReplaceContextInput(node, context); 2105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if we need to convert the {receiver}. 2107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_sloppy(shared->language_mode()) && !shared->native() && 2108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch !receiver_type->Is(Type::Receiver())) { 2109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver = effect = 2110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(javascript()->ConvertReceiver(convert_mode), 211162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch receiver, context, effect, control); 2112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ReplaceValueInput(node, receiver, 1); 2113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Update the effect dependency for the {node}. 2116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ReplaceEffectInput(node, effect); 2117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compute flags for the call. 2119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; 2120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (p.tail_call_mode() == TailCallMode::kAllow) { 2121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch flags |= CallDescriptor::kSupportsTailCalls; 2122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* new_target = jsgraph()->UndefinedConstant(); 2125c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* argument_count = jsgraph()->Constant(arity); 2126f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (NeedsArgumentAdaptorFrame(shared, arity)) { 2127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Patch {node} to an indirect call via the ArgumentsAdaptorTrampoline. 2128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Callable callable = CodeFactory::ArgumentAdaptor(isolate()); 2129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 0, 2130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->HeapConstant(callable.code())); 2131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 2, new_target); 2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 3, argument_count); 2133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput( 2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->zone(), 4, 2135c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch jsgraph()->Constant(shared->internal_formal_parameter_count())); 2136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp( 2137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node, common()->Call(Linkage::GetStubCallDescriptor( 2138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate(), graph()->zone(), callable.descriptor(), 2139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1 + arity, flags))); 2140c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else if (is_builtin && Builtins::HasCppImplementation(builtin_index) && 2141c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ((flags & CallDescriptor::kSupportsTailCalls) == 0)) { 2142f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Patch {node} to a direct CEntryStub call. 2143f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ReduceBuiltin(isolate(), jsgraph(), node, builtin_index, arity, flags); 2144f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } else { 2145f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Patch {node} to a direct call. 2146f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->InsertInput(graph()->zone(), arity + 2, new_target); 2147f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch node->InsertInput(graph()->zone(), arity + 3, argument_count); 2148f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch NodeProperties::ChangeOp(node, 2149f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch common()->Call(Linkage::GetJSCallDescriptor( 2150f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch graph()->zone(), false, 1 + arity, flags))); 2151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 2153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if {target} is a JSFunction. 2156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (target_type->Is(Type::Function())) { 2157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compute flags for the call. 2158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; 2159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (p.tail_call_mode() == TailCallMode::kAllow) { 2160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch flags |= CallDescriptor::kSupportsTailCalls; 2161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Patch {node} to an indirect call via the CallFunction builtin. 2164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Callable callable = CodeFactory::CallFunction(isolate(), convert_mode); 2165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->InsertInput(graph()->zone(), 0, 2166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jsgraph()->HeapConstant(callable.code())); 2167c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch node->InsertInput(graph()->zone(), 2, jsgraph()->Constant(arity)); 2168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp( 2169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node, common()->Call(Linkage::GetStubCallDescriptor( 2170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate(), graph()->zone(), callable.descriptor(), 1 + arity, 2171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch flags))); 2172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 2173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Maybe we did at least learn something about the {receiver}. 2176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (p.convert_mode() != convert_mode) { 2177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp( 217862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node, 217962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch javascript()->Call(p.arity(), p.frequency(), p.feedback(), convert_mode, 218062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch p.tail_call_mode())); 2181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 2182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return NoChange(); 2185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochReduction JSTypedLowering::ReduceJSForInNext(Node* node) { 2189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(IrOpcode::kJSForInNext, node->opcode()); 2190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* receiver = NodeProperties::GetValueInput(node, 0); 2191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* cache_array = NodeProperties::GetValueInput(node, 1); 2192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* cache_type = NodeProperties::GetValueInput(node, 2); 2193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* index = NodeProperties::GetValueInput(node, 3); 2194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* context = NodeProperties::GetContextInput(node); 2195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* frame_state = NodeProperties::GetFrameStateInput(node); 2196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect = NodeProperties::GetEffectInput(node); 2197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control = NodeProperties::GetControlInput(node); 2198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 219962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // We don't support lowering JSForInNext inside try blocks. 220062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (NodeProperties::IsExceptionalCall(node)) return NoChange(); 220162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 220262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // We know that the {index} is in Unsigned32 range here, otherwise executing 220362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // the JSForInNext wouldn't be valid. Unfortunately due to OSR and generators 220462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // this is not always reflected in the types, hence we might need to rename 220562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // the {index} here. 220662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!NodeProperties::GetType(index)->Is(Type::Unsigned32())) { 220762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch index = graph()->NewNode(common()->TypeGuard(Type::Unsigned32()), index, 220862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch control); 220962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 221062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 2211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Load the next {key} from the {cache_array}. 2212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* key = effect = graph()->NewNode( 2213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), 2214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cache_array, index, effect, control); 2215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Load the map of the {receiver}. 2217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* receiver_map = effect = 2218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), 2219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver, effect, control); 2220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if the expected map still matches that of the {receiver}. 2222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* check0 = graph()->NewNode(simplified()->ReferenceEqual(), receiver_map, 2223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cache_type); 2224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* branch0 = 2225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); 2226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 2228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* etrue0; 2229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* vtrue0; 2230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 2231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Don't need filtering since expected map still matches that of the 2232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // {receiver}. 2233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch etrue0 = effect; 2234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vtrue0 = key; 2235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); 2238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* efalse0; 2239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* vfalse0; 2240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 2241109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Filter the {key} to check if it's still a valid property of the 2242109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // {receiver} (does the ToName conversion implicitly). 2243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Callable const callable = CodeFactory::ForInFilter(isolate()); 2244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( 2245f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate(), graph()->zone(), callable.descriptor(), 0, 2246f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CallDescriptor::kNeedsFrameState); 2247109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vfalse0 = efalse0 = graph()->NewNode( 2248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch common()->Call(desc), jsgraph()->HeapConstant(callable.code()), key, 2249f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch receiver, context, frame_state, effect, if_false0); 2250109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0); 2251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); 2254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); 2255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReplaceWithValue(node, node, effect, control); 2256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(0, vtrue0); 2257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(1, vfalse0); 2258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->ReplaceInput(2, control); 2259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->TrimInputCount(3); 2260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeProperties::ChangeOp(node, 2261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch common()->Phi(MachineRepresentation::kTagged, 2)); 2262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Changed(node); 2263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 226562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceJSLoadMessage(Node* node) { 226662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(IrOpcode::kJSLoadMessage, node->opcode()); 226762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ExternalReference const ref = 226862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ExternalReference::address_of_pending_message_obj(isolate()); 226962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node->ReplaceInput(0, jsgraph()->ExternalConstant(ref)); 227062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch NodeProperties::ChangeOp( 227162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node, simplified()->LoadField(AccessBuilder::ForExternalTaggedValue())); 227262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Changed(node); 227362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 227462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 227562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceJSStoreMessage(Node* node) { 227662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(IrOpcode::kJSStoreMessage, node->opcode()); 227762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ExternalReference const ref = 227862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ExternalReference::address_of_pending_message_obj(isolate()); 227962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* value = NodeProperties::GetValueInput(node, 0); 228062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node->ReplaceInput(0, jsgraph()->ExternalConstant(ref)); 228162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node->ReplaceInput(1, value); 228262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch NodeProperties::ChangeOp( 228362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node, simplified()->StoreField(AccessBuilder::ForExternalTaggedValue())); 228462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Changed(node); 228562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 228662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 228713e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochReduction JSTypedLowering::ReduceJSGeneratorStore(Node* node) { 228813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(IrOpcode::kJSGeneratorStore, node->opcode()); 228913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* generator = NodeProperties::GetValueInput(node, 0); 229013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* continuation = NodeProperties::GetValueInput(node, 1); 229113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* offset = NodeProperties::GetValueInput(node, 2); 229213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* context = NodeProperties::GetContextInput(node); 229313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* effect = NodeProperties::GetEffectInput(node); 229413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* control = NodeProperties::GetControlInput(node); 229513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch int register_count = OpParameter<int>(node); 229613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 229762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FieldAccess array_field = AccessBuilder::ForJSGeneratorObjectRegisterFile(); 229813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FieldAccess context_field = AccessBuilder::ForJSGeneratorObjectContext(); 229913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FieldAccess continuation_field = 230013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch AccessBuilder::ForJSGeneratorObjectContinuation(); 230113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FieldAccess input_or_debug_pos_field = 230213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch AccessBuilder::ForJSGeneratorObjectInputOrDebugPos(); 230313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 230413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* array = effect = graph()->NewNode(simplified()->LoadField(array_field), 230513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch generator, effect, control); 230613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 230713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch for (int i = 0; i < register_count; ++i) { 230813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* value = NodeProperties::GetValueInput(node, 3 + i); 230913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch effect = graph()->NewNode( 231013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch simplified()->StoreField(AccessBuilder::ForFixedArraySlot(i)), array, 231113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch value, effect, control); 231213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 231313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 231413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch effect = graph()->NewNode(simplified()->StoreField(context_field), generator, 231513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch context, effect, control); 231613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch effect = graph()->NewNode(simplified()->StoreField(continuation_field), 231713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch generator, continuation, effect, control); 231813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch effect = graph()->NewNode(simplified()->StoreField(input_or_debug_pos_field), 231913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch generator, offset, effect, control); 232013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 232113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ReplaceWithValue(node, effect, effect, control); 232213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Changed(effect); 232313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 232413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 232513e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochReduction JSTypedLowering::ReduceJSGeneratorRestoreContinuation(Node* node) { 232613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(IrOpcode::kJSGeneratorRestoreContinuation, node->opcode()); 232713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* generator = NodeProperties::GetValueInput(node, 0); 232813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* effect = NodeProperties::GetEffectInput(node); 232913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* control = NodeProperties::GetControlInput(node); 233013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 233113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FieldAccess continuation_field = 233213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch AccessBuilder::ForJSGeneratorObjectContinuation(); 233313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 233413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* continuation = effect = graph()->NewNode( 233513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch simplified()->LoadField(continuation_field), generator, effect, control); 233613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* executing = jsgraph()->Constant(JSGeneratorObject::kGeneratorExecuting); 233713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch effect = graph()->NewNode(simplified()->StoreField(continuation_field), 233813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch generator, executing, effect, control); 233913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 234013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ReplaceWithValue(node, continuation, effect, control); 234113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Changed(continuation); 234213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 234313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 234413e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochReduction JSTypedLowering::ReduceJSGeneratorRestoreRegister(Node* node) { 234513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(IrOpcode::kJSGeneratorRestoreRegister, node->opcode()); 234613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* generator = NodeProperties::GetValueInput(node, 0); 234713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* effect = NodeProperties::GetEffectInput(node); 234813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* control = NodeProperties::GetControlInput(node); 234913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch int index = OpParameter<int>(node); 235013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 235162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FieldAccess array_field = AccessBuilder::ForJSGeneratorObjectRegisterFile(); 235213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FieldAccess element_field = AccessBuilder::ForFixedArraySlot(index); 235313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 235413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* array = effect = graph()->NewNode(simplified()->LoadField(array_field), 235513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch generator, effect, control); 235613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* element = effect = graph()->NewNode( 235713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch simplified()->LoadField(element_field), array, effect, control); 235813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* stale = jsgraph()->StaleRegisterConstant(); 235913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch effect = graph()->NewNode(simplified()->StoreField(element_field), array, 236013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch stale, effect, control); 236113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 236213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ReplaceWithValue(node, element, effect, control); 236313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Changed(element); 236413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 2365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::Reduce(Node* node) { 2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (node->opcode()) { 2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSEqual: 2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReduceJSEqual(node, false); 2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSNotEqual: 2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReduceJSEqual(node, true); 2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSStrictEqual: 2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReduceJSStrictEqual(node, false); 2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSStrictNotEqual: 2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReduceJSStrictEqual(node, true); 2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSLessThan: // fall through 2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSGreaterThan: // fall through 2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSLessThanOrEqual: // fall through 2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSGreaterThanOrEqual: 2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReduceJSComparison(node); 2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSBitwiseOr: 2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSBitwiseXor: 2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSBitwiseAnd: 2384f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return ReduceInt32Binop(node); 2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSShiftLeft: 2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSShiftRight: 2387f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return ReduceUI32Shift(node, kSigned); 2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSShiftRightLogical: 2389f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return ReduceUI32Shift(node, kUnsigned); 2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSAdd: 2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReduceJSAdd(node); 2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSSubtract: 2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSMultiply: 2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSDivide: 2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSModulus: 2396f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return ReduceNumberBinop(node); 2397f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch case IrOpcode::kJSOrdinaryHasInstance: 2398f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return ReduceJSOrdinaryHasInstance(node); 2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSToBoolean: 2400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ReduceJSToBoolean(node); 24013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case IrOpcode::kJSToInteger: 24023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return ReduceJSToInteger(node); 24033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case IrOpcode::kJSToLength: 24043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return ReduceJSToLength(node); 2405c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case IrOpcode::kJSToName: 2406c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return ReduceJSToName(node); 2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSToNumber: 2408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ReduceJSToNumber(node); 2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSToString: 2410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ReduceJSToString(node); 2411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSToObject: 2412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ReduceJSToObject(node); 2413c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case IrOpcode::kJSTypeOf: 2414c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return ReduceJSTypeOf(node); 2415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSLoadNamed: 2416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ReduceJSLoadNamed(node); 2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSLoadProperty: 2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReduceJSLoadProperty(node); 2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kJSStoreProperty: 2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ReduceJSStoreProperty(node); 2421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kJSLoadContext: 2422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ReduceJSLoadContext(node); 2423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kJSStoreContext: 2424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return ReduceJSStoreContext(node); 2425c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case IrOpcode::kJSLoadModule: 2426c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return ReduceJSLoadModule(node); 2427c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case IrOpcode::kJSStoreModule: 2428c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return ReduceJSStoreModule(node); 2429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSConvertReceiver: 2430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ReduceJSConvertReceiver(node); 243162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case IrOpcode::kJSConstruct: 243262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return ReduceJSConstruct(node); 243362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case IrOpcode::kJSCallForwardVarargs: 243462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return ReduceJSCallForwardVarargs(node); 243562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case IrOpcode::kJSCall: 243662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return ReduceJSCall(node); 2437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kJSForInNext: 2438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ReduceJSForInNext(node); 243962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case IrOpcode::kJSLoadMessage: 244062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return ReduceJSLoadMessage(node); 244162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case IrOpcode::kJSStoreMessage: 244262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return ReduceJSStoreMessage(node); 244313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case IrOpcode::kJSGeneratorStore: 244413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return ReduceJSGeneratorStore(node); 244513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case IrOpcode::kJSGeneratorRestoreContinuation: 244613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return ReduceJSGeneratorRestoreContinuation(node); 244713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case IrOpcode::kJSGeneratorRestoreRegister: 244813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return ReduceJSGeneratorRestoreRegister(node); 244962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(mstarzinger): Simplified operations hiding in JS-level reducer not 245062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // fooling anyone. Consider moving this into a separate reducer. 245162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case IrOpcode::kSpeculativeNumberAdd: 245262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return ReduceSpeculativeNumberAdd(node); 245362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case IrOpcode::kSpeculativeNumberSubtract: 245462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case IrOpcode::kSpeculativeNumberMultiply: 245562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case IrOpcode::kSpeculativeNumberDivide: 245662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case IrOpcode::kSpeculativeNumberModulus: 245762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return ReduceSpeculativeNumberBinop(node); 2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoChange(); 2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierFactory* JSTypedLowering::factory() const { return jsgraph()->factory(); } 2466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierGraph* JSTypedLowering::graph() const { return jsgraph()->graph(); } 2469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochIsolate* JSTypedLowering::isolate() const { return jsgraph()->isolate(); } 2472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierJSOperatorBuilder* JSTypedLowering::javascript() const { 2475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return jsgraph()->javascript(); 2476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierCommonOperatorBuilder* JSTypedLowering::common() const { 2480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return jsgraph()->common(); 2481958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2482958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSimplifiedOperatorBuilder* JSTypedLowering::simplified() const { 2484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return jsgraph()->simplified(); 2485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochCompilationDependencies* JSTypedLowering::dependencies() const { 2489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return dependencies_; 2490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace compiler 2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace internal 2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace v8 2495