[turbofan] Make Strict(Not)Equal, TypeOf, ToBoolean, UnaryNot effectful.
This is necessary because these operators can read heap (equality can actually write heap when flattening strings). BUG=v8:4446 LOG=n Review URL: https://codereview.chromium.org/1374683002 Cr-Commit-Position: refs/heads/master@{#31005}
This commit is contained in:
parent
92a7012b8b
commit
d06930fc4b
@ -149,17 +149,19 @@ void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token,
|
||||
inputs.push_back(NodeProperties::GetValueInput(node, 0));
|
||||
inputs.push_back(NodeProperties::GetValueInput(node, 1));
|
||||
inputs.push_back(NodeProperties::GetContextInput(node));
|
||||
if (node->op()->HasProperty(Operator::kPure)) {
|
||||
// A pure (strict) comparison doesn't have an effect, control or frame
|
||||
// state. But for the graph, we need to add control and effect inputs.
|
||||
DCHECK(OperatorProperties::GetFrameStateInputCount(node->op()) == 0);
|
||||
inputs.push_back(graph()->start());
|
||||
inputs.push_back(graph()->start());
|
||||
} else {
|
||||
// Some comparisons (StrictEqual) don't have an effect, control or frame
|
||||
// state inputs, so handle those cases here.
|
||||
if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
|
||||
inputs.push_back(NodeProperties::GetFrameStateInput(node, 0));
|
||||
inputs.push_back(NodeProperties::GetEffectInput(node));
|
||||
inputs.push_back(NodeProperties::GetControlInput(node));
|
||||
}
|
||||
Node* effect = (node->op()->EffectInputCount() > 0)
|
||||
? NodeProperties::GetEffectInput(node)
|
||||
: graph()->start();
|
||||
inputs.push_back(effect);
|
||||
Node* control = (node->op()->ControlInputCount() > 0)
|
||||
? NodeProperties::GetControlInput(node)
|
||||
: graph()->start();
|
||||
inputs.push_back(control);
|
||||
CallDescriptor* desc_compare = Linkage::GetStubCallDescriptor(
|
||||
isolate(), zone(), callable.descriptor(), 0,
|
||||
CallDescriptor::kPatchableCallSiteWithNop | FlagsForNode(node),
|
||||
|
@ -454,10 +454,10 @@ const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) {
|
||||
#define CACHED_OP_LIST(V) \
|
||||
V(Equal, Operator::kNoProperties, 2, 1) \
|
||||
V(NotEqual, Operator::kNoProperties, 2, 1) \
|
||||
V(StrictEqual, Operator::kPure, 2, 1) \
|
||||
V(StrictNotEqual, Operator::kPure, 2, 1) \
|
||||
V(UnaryNot, Operator::kPure, 1, 1) \
|
||||
V(ToBoolean, Operator::kPure, 1, 1) \
|
||||
V(StrictEqual, Operator::kNoThrow, 2, 1) \
|
||||
V(StrictNotEqual, Operator::kNoThrow, 2, 1) \
|
||||
V(UnaryNot, Operator::kEliminatable, 1, 1) \
|
||||
V(ToBoolean, Operator::kEliminatable, 1, 1) \
|
||||
V(ToNumber, Operator::kNoProperties, 1, 1) \
|
||||
V(ToString, Operator::kNoProperties, 1, 1) \
|
||||
V(ToName, Operator::kNoProperties, 1, 1) \
|
||||
@ -465,7 +465,7 @@ const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) {
|
||||
V(Yield, Operator::kNoProperties, 1, 1) \
|
||||
V(Create, Operator::kEliminatable, 0, 1) \
|
||||
V(HasProperty, Operator::kNoProperties, 2, 1) \
|
||||
V(TypeOf, Operator::kPure, 1, 1) \
|
||||
V(TypeOf, Operator::kEliminatable, 1, 1) \
|
||||
V(InstanceOf, Operator::kNoProperties, 2, 1) \
|
||||
V(ForInDone, Operator::kPure, 2, 1) \
|
||||
V(ForInNext, Operator::kNoProperties, 4, 1) \
|
||||
|
@ -576,7 +576,7 @@ Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) {
|
||||
// x === x is always true if x != NaN
|
||||
if (!r.left_type()->Maybe(Type::NaN())) {
|
||||
Node* replacement = jsgraph()->BooleanConstant(!invert);
|
||||
Replace(node, replacement);
|
||||
ReplaceWithValue(node, replacement);
|
||||
return Replace(replacement);
|
||||
}
|
||||
}
|
||||
@ -585,7 +585,7 @@ Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) {
|
||||
// empty type intersection means the values cannot be strictly equal.
|
||||
if (!r.left_type()->Maybe(r.right_type())) {
|
||||
Node* replacement = jsgraph()->BooleanConstant(invert);
|
||||
Replace(node, replacement);
|
||||
ReplaceWithValue(node, replacement);
|
||||
return Replace(replacement);
|
||||
}
|
||||
}
|
||||
@ -629,12 +629,15 @@ Reduction JSTypedLowering::ReduceJSUnaryNot(Node* node) {
|
||||
Type* const input_type = NodeProperties::GetType(input);
|
||||
if (input_type->Is(Type::Boolean())) {
|
||||
// JSUnaryNot(x:boolean) => BooleanNot(x)
|
||||
RelaxEffectsAndControls(node);
|
||||
node->TrimInputCount(1);
|
||||
NodeProperties::ChangeOp(node, simplified()->BooleanNot());
|
||||
return Changed(node);
|
||||
} else if (input_type->Is(Type::OrderedNumber())) {
|
||||
// JSUnaryNot(x:number) => NumberEqual(x,#0)
|
||||
RelaxEffectsAndControls(node);
|
||||
node->ReplaceInput(1, jsgraph()->ZeroConstant());
|
||||
node->TrimInputCount(2);
|
||||
NodeProperties::ChangeOp(node, simplified()->NumberEqual());
|
||||
return Changed(node);
|
||||
} else if (input_type->Is(Type::String())) {
|
||||
@ -647,6 +650,7 @@ Reduction JSTypedLowering::ReduceJSUnaryNot(Node* node) {
|
||||
ReplaceWithValue(node, node, length);
|
||||
node->ReplaceInput(0, length);
|
||||
node->ReplaceInput(1, jsgraph()->ZeroConstant());
|
||||
node->TrimInputCount(2);
|
||||
NodeProperties::ChangeOp(node, simplified()->NumberEqual());
|
||||
return Changed(node);
|
||||
}
|
||||
@ -659,9 +663,11 @@ Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
|
||||
Type* const input_type = NodeProperties::GetType(input);
|
||||
if (input_type->Is(Type::Boolean())) {
|
||||
// JSToBoolean(x:boolean) => x
|
||||
ReplaceWithValue(node, input);
|
||||
return Replace(input);
|
||||
} else if (input_type->Is(Type::OrderedNumber())) {
|
||||
// JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0))
|
||||
RelaxEffectsAndControls(node);
|
||||
node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input,
|
||||
jsgraph()->ZeroConstant()));
|
||||
node->TrimInputCount(1);
|
||||
@ -674,8 +680,10 @@ Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
|
||||
// chain) because we assume String::length to be immutable.
|
||||
Node* length = graph()->NewNode(simplified()->LoadField(access), input,
|
||||
graph()->start(), graph()->start());
|
||||
ReplaceWithValue(node, node, length);
|
||||
node->ReplaceInput(0, jsgraph()->ZeroConstant());
|
||||
node->ReplaceInput(1, length);
|
||||
node->TrimInputCount(2);
|
||||
NodeProperties::ChangeOp(node, simplified()->NumberLessThan());
|
||||
return Changed(node);
|
||||
}
|
||||
|
@ -835,19 +835,17 @@ void CheckEqualityReduction(JSTypedLoweringTester* R, bool strict, Node* l,
|
||||
Node* p1 = j == 1 ? l : r;
|
||||
|
||||
{
|
||||
Node* eq = strict
|
||||
? R->graph.NewNode(R->javascript.StrictEqual(), p0, p1,
|
||||
R->context())
|
||||
: R->Binop(R->javascript.Equal(), p0, p1);
|
||||
const Operator* op =
|
||||
strict ? R->javascript.StrictEqual() : R->javascript.Equal();
|
||||
Node* eq = R->Binop(op, p0, p1);
|
||||
Node* r = R->reduce(eq);
|
||||
R->CheckPureBinop(expected, r);
|
||||
}
|
||||
|
||||
{
|
||||
Node* ne = strict
|
||||
? R->graph.NewNode(R->javascript.StrictNotEqual(), p0, p1,
|
||||
R->context())
|
||||
: R->Binop(R->javascript.NotEqual(), p0, p1);
|
||||
const Operator* op =
|
||||
strict ? R->javascript.StrictNotEqual() : R->javascript.NotEqual();
|
||||
Node* ne = R->Binop(op, p0, p1);
|
||||
Node* n = R->reduce(ne);
|
||||
CHECK_EQ(IrOpcode::kBooleanNot, n->opcode());
|
||||
Node* r = n->InputAt(0);
|
||||
|
@ -310,7 +310,7 @@ TEST_F(JSIntrinsicLoweringTest, Likely) {
|
||||
graph()->NewNode(javascript()->CallRuntime(Runtime::kInlineLikely, 1),
|
||||
input, context, effect, control);
|
||||
Node* const to_boolean =
|
||||
graph()->NewNode(javascript()->ToBoolean(), likely, context);
|
||||
graph()->NewNode(javascript()->ToBoolean(), likely, context, effect);
|
||||
Diamond d(graph(), common(), to_boolean);
|
||||
graph()->SetEnd(graph()->NewNode(common()->End(1), d.merge));
|
||||
|
||||
@ -405,7 +405,7 @@ TEST_F(JSIntrinsicLoweringTest, Unlikely) {
|
||||
graph()->NewNode(javascript()->CallRuntime(Runtime::kInlineUnlikely, 1),
|
||||
input, context, effect, control);
|
||||
Node* const to_boolean =
|
||||
graph()->NewNode(javascript()->ToBoolean(), unlikely, context);
|
||||
graph()->NewNode(javascript()->ToBoolean(), unlikely, context, effect);
|
||||
Diamond d(graph(), common(), to_boolean);
|
||||
graph()->SetEnd(graph()->NewNode(common()->End(1), d.merge));
|
||||
|
||||
|
@ -69,10 +69,10 @@ const SharedOperator kSharedOperators[] = {
|
||||
}
|
||||
SHARED(Equal, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
|
||||
SHARED(NotEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
|
||||
SHARED(StrictEqual, Operator::kPure, 2, 0, 0, 0, 1, 0, 0),
|
||||
SHARED(StrictNotEqual, Operator::kPure, 2, 0, 0, 0, 1, 0, 0),
|
||||
SHARED(UnaryNot, Operator::kPure, 1, 0, 0, 0, 1, 0, 0),
|
||||
SHARED(ToBoolean, Operator::kPure, 1, 0, 0, 0, 1, 0, 0),
|
||||
SHARED(StrictEqual, Operator::kNoThrow, 2, 0, 1, 1, 1, 1, 0),
|
||||
SHARED(StrictNotEqual, Operator::kNoThrow, 2, 0, 1, 1, 1, 1, 0),
|
||||
SHARED(UnaryNot, Operator::kEliminatable, 1, 0, 1, 0, 1, 1, 0),
|
||||
SHARED(ToBoolean, Operator::kEliminatable, 1, 0, 1, 0, 1, 1, 0),
|
||||
SHARED(ToNumber, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2),
|
||||
SHARED(ToString, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2),
|
||||
SHARED(ToName, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2),
|
||||
@ -80,7 +80,7 @@ const SharedOperator kSharedOperators[] = {
|
||||
SHARED(Yield, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2),
|
||||
SHARED(Create, Operator::kEliminatable, 0, 0, 1, 0, 1, 1, 0),
|
||||
SHARED(HasProperty, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
|
||||
SHARED(TypeOf, Operator::kPure, 1, 0, 0, 0, 1, 0, 0),
|
||||
SHARED(TypeOf, Operator::kEliminatable, 1, 0, 1, 0, 1, 1, 0),
|
||||
SHARED(InstanceOf, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
|
||||
SHARED(CreateFunctionContext, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2),
|
||||
SHARED(CreateWithContext, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
|
||||
|
@ -112,8 +112,8 @@ class JSTypedLoweringTest : public TypedGraphTest {
|
||||
TEST_F(JSTypedLoweringTest, JSUnaryNotWithBoolean) {
|
||||
Node* input = Parameter(Type::Boolean(), 0);
|
||||
Node* context = Parameter(Type::Any(), 1);
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->UnaryNot(), input,
|
||||
context, graph()->start()));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsBooleanNot(input));
|
||||
}
|
||||
@ -122,8 +122,8 @@ TEST_F(JSTypedLoweringTest, JSUnaryNotWithBoolean) {
|
||||
TEST_F(JSTypedLoweringTest, JSUnaryNotWithOrderedNumber) {
|
||||
Node* input = Parameter(Type::OrderedNumber(), 0);
|
||||
Node* context = Parameter(Type::Any(), 1);
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->UnaryNot(), input,
|
||||
context, graph()->start()));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsNumberEqual(input, IsNumberConstant(0)));
|
||||
}
|
||||
@ -151,8 +151,8 @@ TEST_F(JSTypedLoweringTest, JSUnaryNotWithFalsish) {
|
||||
zone()),
|
||||
0);
|
||||
Node* context = Parameter(Type::Any(), 1);
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->UnaryNot(), input,
|
||||
context, graph()->start()));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsTrueConstant());
|
||||
}
|
||||
@ -166,8 +166,8 @@ TEST_F(JSTypedLoweringTest, JSUnaryNotWithTruish) {
|
||||
zone()),
|
||||
0);
|
||||
Node* context = Parameter(Type::Any(), 1);
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->UnaryNot(), input,
|
||||
context, graph()->start()));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsFalseConstant());
|
||||
}
|
||||
@ -176,8 +176,8 @@ TEST_F(JSTypedLoweringTest, JSUnaryNotWithTruish) {
|
||||
TEST_F(JSTypedLoweringTest, JSUnaryNotWithNonZeroPlainNumber) {
|
||||
Node* input = Parameter(Type::Range(1.0, 42.0, zone()), 0);
|
||||
Node* context = Parameter(Type::Any(), 1);
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->UnaryNot(), input,
|
||||
context, graph()->start()));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsFalseConstant());
|
||||
}
|
||||
@ -186,8 +186,8 @@ TEST_F(JSTypedLoweringTest, JSUnaryNotWithNonZeroPlainNumber) {
|
||||
TEST_F(JSTypedLoweringTest, JSUnaryNotWithString) {
|
||||
Node* input = Parameter(Type::String(), 0);
|
||||
Node* context = Parameter(Type::Any(), 1);
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->UnaryNot(), input,
|
||||
context, graph()->start()));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(
|
||||
r.replacement(),
|
||||
@ -200,8 +200,8 @@ TEST_F(JSTypedLoweringTest, JSUnaryNotWithString) {
|
||||
TEST_F(JSTypedLoweringTest, JSUnaryNotWithAny) {
|
||||
Node* input = Parameter(Type::Any(), 0);
|
||||
Node* context = Parameter(Type::Any(), 1);
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->UnaryNot(), input,
|
||||
context, graph()->start()));
|
||||
ASSERT_FALSE(r.Changed());
|
||||
}
|
||||
|
||||
@ -307,8 +307,8 @@ TEST_F(JSTypedLoweringTest, ParameterWithUndefined) {
|
||||
TEST_F(JSTypedLoweringTest, JSToBooleanWithBoolean) {
|
||||
Node* input = Parameter(Type::Boolean(), 0);
|
||||
Node* context = Parameter(Type::Any(), 1);
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ToBoolean(), input,
|
||||
context, graph()->start()));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_EQ(input, r.replacement());
|
||||
}
|
||||
@ -336,8 +336,8 @@ TEST_F(JSTypedLoweringTest, JSToBooleanWithFalsish) {
|
||||
zone()),
|
||||
0);
|
||||
Node* context = Parameter(Type::Any(), 1);
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ToBoolean(), input,
|
||||
context, graph()->start()));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsFalseConstant());
|
||||
}
|
||||
@ -351,8 +351,8 @@ TEST_F(JSTypedLoweringTest, JSToBooleanWithTruish) {
|
||||
zone()),
|
||||
0);
|
||||
Node* context = Parameter(Type::Any(), 1);
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ToBoolean(), input,
|
||||
context, graph()->start()));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsTrueConstant());
|
||||
}
|
||||
@ -361,8 +361,8 @@ TEST_F(JSTypedLoweringTest, JSToBooleanWithTruish) {
|
||||
TEST_F(JSTypedLoweringTest, JSToBooleanWithNonZeroPlainNumber) {
|
||||
Node* input = Parameter(Type::Range(1, V8_INFINITY, zone()), 0);
|
||||
Node* context = Parameter(Type::Any(), 1);
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ToBoolean(), input,
|
||||
context, graph()->start()));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsTrueConstant());
|
||||
}
|
||||
@ -371,8 +371,8 @@ TEST_F(JSTypedLoweringTest, JSToBooleanWithNonZeroPlainNumber) {
|
||||
TEST_F(JSTypedLoweringTest, JSToBooleanWithOrderedNumber) {
|
||||
Node* input = Parameter(Type::OrderedNumber(), 0);
|
||||
Node* context = Parameter(Type::Any(), 1);
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ToBoolean(), input,
|
||||
context, graph()->start()));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(),
|
||||
IsBooleanNot(IsNumberEqual(input, IsNumberConstant(0.0))));
|
||||
@ -382,8 +382,8 @@ TEST_F(JSTypedLoweringTest, JSToBooleanWithOrderedNumber) {
|
||||
TEST_F(JSTypedLoweringTest, JSToBooleanWithString) {
|
||||
Node* input = Parameter(Type::String(), 0);
|
||||
Node* context = Parameter(Type::Any(), 1);
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ToBoolean(), input,
|
||||
context, graph()->start()));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(
|
||||
r.replacement(),
|
||||
@ -396,8 +396,8 @@ TEST_F(JSTypedLoweringTest, JSToBooleanWithString) {
|
||||
TEST_F(JSTypedLoweringTest, JSToBooleanWithAny) {
|
||||
Node* input = Parameter(Type::Any(), 0);
|
||||
Node* context = Parameter(Type::Any(), 1);
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->ToBoolean(), input,
|
||||
context, graph()->start()));
|
||||
ASSERT_FALSE(r.Changed());
|
||||
}
|
||||
|
||||
@ -429,8 +429,9 @@ TEST_F(JSTypedLoweringTest, JSStrictEqualWithTheHole) {
|
||||
Node* const context = UndefinedConstant();
|
||||
TRACED_FOREACH(Type*, type, kJSTypes) {
|
||||
Node* const lhs = Parameter(type);
|
||||
Reduction r = Reduce(
|
||||
graph()->NewNode(javascript()->StrictEqual(), lhs, the_hole, context));
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->StrictEqual(), lhs, the_hole,
|
||||
context, graph()->start(), graph()->start()));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsFalseConstant());
|
||||
}
|
||||
@ -442,7 +443,8 @@ TEST_F(JSTypedLoweringTest, JSStrictEqualWithUnique) {
|
||||
Node* const rhs = Parameter(Type::Unique(), 1);
|
||||
Node* const context = Parameter(Type::Any(), 2);
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->StrictEqual(), lhs, rhs, context));
|
||||
Reduce(graph()->NewNode(javascript()->StrictEqual(), lhs, rhs, context,
|
||||
graph()->start(), graph()->start()));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsReferenceEqual(Type::Unique(), lhs, rhs));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user