Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1231)

Side by Side Diff: runtime/vm/intermediate_language.cc

Issue 10977021: Fix incorrect strict not-equal comparison when both arguments are constants. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/language/strict_equal_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/dart_entry.h" 8 #include "vm/dart_entry.h"
9 #include "vm/flow_graph_allocator.h" 9 #include "vm/flow_graph_allocator.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 1555 matching lines...) Expand 10 before | Expand all | Expand 10 after
1566 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1566 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1567 locs->set_in(0, Location::RegisterOrConstant(left())); 1567 locs->set_in(0, Location::RegisterOrConstant(left()));
1568 locs->set_in(1, Location::RegisterOrConstant(right())); 1568 locs->set_in(1, Location::RegisterOrConstant(right()));
1569 locs->set_out(Location::RequiresRegister()); 1569 locs->set_out(Location::RequiresRegister());
1570 return locs; 1570 return locs;
1571 } 1571 }
1572 1572
1573 1573
1574 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1574 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1575 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 1575 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
1576 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
1577 Location left = locs()->in(0); 1576 Location left = locs()->in(0);
1578 Location right = locs()->in(1); 1577 Location right = locs()->in(1);
1579 if (left.IsConstant() && right.IsConstant()) { 1578 if (left.IsConstant() && right.IsConstant()) {
1580 // TODO(vegorov): should be eliminated earlier by constant propagation. 1579 // TODO(vegorov): should be eliminated earlier by constant propagation.
1581 const bool result = left.constant().raw() == right.constant().raw(); 1580 const bool result = (kind() == Token::kEQ_STRICT) ?
1581 left.constant().raw() == right.constant().raw() :
1582 left.constant().raw() != right.constant().raw();
1582 __ LoadObject(locs()->out().reg(), result ? compiler->bool_true() : 1583 __ LoadObject(locs()->out().reg(), result ? compiler->bool_true() :
1583 compiler->bool_false()); 1584 compiler->bool_false());
1584 return; 1585 return;
1585 } 1586 }
1586 if (left.IsConstant()) { 1587 if (left.IsConstant()) {
1587 __ CompareObject(right.reg(), left.constant()); 1588 __ CompareObject(right.reg(), left.constant());
1588 } else if (right.IsConstant()) { 1589 } else if (right.IsConstant()) {
1589 __ CompareObject(left.reg(), right.constant()); 1590 __ CompareObject(left.reg(), right.constant());
1590 } else { 1591 } else {
1591 __ CompareRegisters(left.reg(), right.reg()); 1592 __ CompareRegisters(left.reg(), right.reg());
1592 } 1593 }
1593 1594
1594 Register result = locs()->out().reg(); 1595 Register result = locs()->out().reg();
1595 Label load_true, done; 1596 Label load_true, done;
1597 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
1596 __ j(true_condition, &load_true, Assembler::kNearJump); 1598 __ j(true_condition, &load_true, Assembler::kNearJump);
1597 __ LoadObject(result, compiler->bool_false()); 1599 __ LoadObject(result, compiler->bool_false());
1598 __ jmp(&done, Assembler::kNearJump); 1600 __ jmp(&done, Assembler::kNearJump);
1599 __ Bind(&load_true); 1601 __ Bind(&load_true);
1600 __ LoadObject(result, compiler->bool_true()); 1602 __ LoadObject(result, compiler->bool_true());
1601 __ Bind(&done); 1603 __ Bind(&done);
1602 } 1604 }
1603 1605
1604 1606
1605 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 1607 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
1606 BranchInstr* branch) { 1608 BranchInstr* branch) {
1607 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 1609 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
1608 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
1609 Location left = locs()->in(0); 1610 Location left = locs()->in(0);
1610 Location right = locs()->in(1); 1611 Location right = locs()->in(1);
1611 if (left.IsConstant() && right.IsConstant()) { 1612 if (left.IsConstant() && right.IsConstant()) {
1612 // TODO(vegorov): should be eliminated earlier by constant propagation. 1613 // TODO(vegorov): should be eliminated earlier by constant propagation.
1613 const bool result = left.constant().raw() == right.constant().raw(); 1614 const bool result = (kind() == Token::kEQ_STRICT) ?
1615 left.constant().raw() == right.constant().raw() :
1616 left.constant().raw() != right.constant().raw();
1614 branch->EmitBranchOnValue(compiler, result); 1617 branch->EmitBranchOnValue(compiler, result);
1615 return; 1618 return;
1616 } 1619 }
1617 if (left.IsConstant()) { 1620 if (left.IsConstant()) {
1618 __ CompareObject(right.reg(), left.constant()); 1621 __ CompareObject(right.reg(), left.constant());
1619 } else if (right.IsConstant()) { 1622 } else if (right.IsConstant()) {
1620 __ CompareObject(left.reg(), right.constant()); 1623 __ CompareObject(left.reg(), right.constant());
1621 } else { 1624 } else {
1622 __ CompareRegisters(left.reg(), right.reg()); 1625 __ CompareRegisters(left.reg(), right.reg());
1623 } 1626 }
1624 1627
1628 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
1625 branch->EmitBranchOnCondition(compiler, true_condition); 1629 branch->EmitBranchOnCondition(compiler, true_condition);
1626 } 1630 }
1627 1631
1628 1632
1629 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1633 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1630 // The arguments to the stub include the closure. The arguments 1634 // The arguments to the stub include the closure. The arguments
1631 // descriptor describes the closure's arguments (and so does not include 1635 // descriptor describes the closure's arguments (and so does not include
1632 // the closure). 1636 // the closure).
1633 Register temp_reg = locs()->temp(0).reg(); 1637 Register temp_reg = locs()->temp(0).reg();
1634 int argument_count = ArgumentCount(); 1638 int argument_count = ArgumentCount();
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
2030 new_max = new_max.Clamp(); 2034 new_max = new_max.Clamp();
2031 } 2035 }
2032 2036
2033 return Range::Update(&range_, new_min, new_max); 2037 return Range::Update(&range_, new_min, new_max);
2034 } 2038 }
2035 2039
2036 2040
2037 #undef __ 2041 #undef __
2038 2042
2039 } // namespace dart 2043 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | tests/language/strict_equal_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698