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

Unified Diff: src/code-stub-assembler.cc

Issue 2438683005: [regexp] Move RegExp.prototype[@@search] to TF (Closed)
Patch Set: Rebase Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/code-stub-assembler.h ('k') | test/mjsunit/regexp.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/code-stub-assembler.cc
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
index 6d1c4ca1a7297cff79f468daaf77529033e9907f..7c15dea612e6510b7e6ce4ab669947db91d60844 100644
--- a/src/code-stub-assembler.cc
+++ b/src/code-stub-assembler.cc
@@ -2271,6 +2271,40 @@ void CodeStubAssembler::InitializeAllocationMemento(
}
}
+Node* CodeStubAssembler::TryTaggedToFloat64(Node* value,
+ Label* if_valueisnotnumber) {
+ Label out(this);
+ Variable var_result(this, MachineRepresentation::kFloat64);
+
+ // Check if the {value} is a Smi or a HeapObject.
+ Label if_valueissmi(this), if_valueisnotsmi(this);
+ Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi);
+
+ Bind(&if_valueissmi);
+ {
+ // Convert the Smi {value}.
+ var_result.Bind(SmiToFloat64(value));
+ Goto(&out);
+ }
+
+ Bind(&if_valueisnotsmi);
+ {
+ // Check if {value} is a HeapNumber.
+ Label if_valueisheapnumber(this);
+ Branch(IsHeapNumberMap(LoadMap(value)), &if_valueisheapnumber,
+ if_valueisnotnumber);
+
+ Bind(&if_valueisheapnumber);
+ {
+ // Load the floating point value.
+ var_result.Bind(LoadHeapNumberValue(value));
+ Goto(&out);
+ }
+ }
+ Bind(&out);
+ return var_result.value();
+}
+
Node* CodeStubAssembler::TruncateTaggedToFloat64(Node* context, Node* value) {
// We might need to loop once due to ToNumber conversion.
Variable var_value(this, MachineRepresentation::kTagged),
@@ -2280,42 +2314,23 @@ Node* CodeStubAssembler::TruncateTaggedToFloat64(Node* context, Node* value) {
Goto(&loop);
Bind(&loop);
{
+ Label if_valueisnotnumber(this, Label::kDeferred);
+
// Load the current {value}.
value = var_value.value();
- // Check if the {value} is a Smi or a HeapObject.
- Label if_valueissmi(this), if_valueisnotsmi(this);
- Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi);
-
- Bind(&if_valueissmi);
- {
- // Convert the Smi {value}.
- var_result.Bind(SmiToFloat64(value));
- Goto(&done_loop);
- }
+ // Convert {value} to Float64 if it is a number and convert it to a number
+ // otherwise.
+ Node* const result = TryTaggedToFloat64(value, &if_valueisnotnumber);
+ var_result.Bind(result);
+ Goto(&done_loop);
- Bind(&if_valueisnotsmi);
+ Bind(&if_valueisnotnumber);
{
- // Check if {value} is a HeapNumber.
- Label if_valueisheapnumber(this),
- if_valueisnotheapnumber(this, Label::kDeferred);
- Branch(WordEqual(LoadMap(value), HeapNumberMapConstant()),
- &if_valueisheapnumber, &if_valueisnotheapnumber);
-
- Bind(&if_valueisheapnumber);
- {
- // Load the floating point value.
- var_result.Bind(LoadHeapNumberValue(value));
- Goto(&done_loop);
- }
-
- Bind(&if_valueisnotheapnumber);
- {
- // Convert the {value} to a Number first.
- Callable callable = CodeFactory::NonNumberToNumber(isolate());
- var_value.Bind(CallStub(callable, context, value));
- Goto(&loop);
- }
+ // Convert the {value} to a Number first.
+ Callable callable = CodeFactory::NonNumberToNumber(isolate());
+ var_value.Bind(CallStub(callable, context, value));
+ Goto(&loop);
}
}
Bind(&done_loop);
@@ -6574,24 +6589,7 @@ Node* CodeStubAssembler::PrepareValueForWrite(Node* value,
Representation representation,
Label* bailout) {
if (representation.IsDouble()) {
- Variable var_value(this, MachineRepresentation::kFloat64);
- Label if_smi(this), if_heap_object(this), done(this);
- Branch(TaggedIsSmi(value), &if_smi, &if_heap_object);
- Bind(&if_smi);
- {
- var_value.Bind(SmiToFloat64(value));
- Goto(&done);
- }
- Bind(&if_heap_object);
- {
- GotoUnless(
- Word32Equal(LoadInstanceType(value), Int32Constant(HEAP_NUMBER_TYPE)),
- bailout);
- var_value.Bind(LoadHeapNumberValue(value));
- Goto(&done);
- }
- Bind(&done);
- value = var_value.value();
+ value = TryTaggedToFloat64(value, bailout);
} else if (representation.IsHeapObject()) {
// Field type is checked by the handler, here we only check if the value
// is a heap object.
@@ -8576,6 +8574,95 @@ compiler::Node* CodeStubAssembler::StrictEqual(ResultMode mode,
return result.value();
}
+// ECMA#sec-samevalue
+// This algorithm differs from the Strict Equality Comparison Algorithm in its
+// treatment of signed zeroes and NaNs.
+compiler::Node* CodeStubAssembler::SameValue(compiler::Node* lhs,
+ compiler::Node* rhs,
+ compiler::Node* context) {
+ Variable var_result(this, MachineType::PointerRepresentation());
+ Label strict_equal(this), out(this);
+
+ Node* const int_false = IntPtrConstant(0);
+ Node* const int_true = IntPtrConstant(1);
+
+ Label if_equal(this), if_notequal(this);
+ Branch(WordEqual(lhs, rhs), &if_equal, &if_notequal);
+
+ Bind(&if_equal);
+ {
+ // This covers the case when {lhs} == {rhs}. We can simply return true
+ // because SameValue considers two NaNs to be equal.
+
+ var_result.Bind(int_true);
+ Goto(&out);
+ }
+
+ Bind(&if_notequal);
+ {
+ // This covers the case when {lhs} != {rhs}. We only handle numbers here
+ // and defer to StrictEqual for the rest.
+
+ Node* const lhs_float = TryTaggedToFloat64(lhs, &strict_equal);
+ Node* const rhs_float = TryTaggedToFloat64(rhs, &strict_equal);
+
+ Label if_lhsisnan(this), if_lhsnotnan(this);
+ BranchIfFloat64IsNaN(lhs_float, &if_lhsisnan, &if_lhsnotnan);
+
+ Bind(&if_lhsisnan);
+ {
+ // Return true iff {rhs} is NaN.
+
+ Node* const result =
+ Select(Float64Equal(rhs_float, rhs_float), int_false, int_true,
+ MachineType::PointerRepresentation());
+ var_result.Bind(result);
+ Goto(&out);
+ }
+
+ Bind(&if_lhsnotnan);
+ {
+ Label if_floatisequal(this), if_floatnotequal(this);
+ Branch(Float64Equal(lhs_float, rhs_float), &if_floatisequal,
+ &if_floatnotequal);
+
+ Bind(&if_floatisequal);
+ {
+ // We still need to handle the case when {lhs} and {rhs} are -0.0 and
+ // 0.0 (or vice versa). Compare the high word to
+ // distinguish between the two.
+
+ Node* const lhs_hi_word = Float64ExtractHighWord32(lhs_float);
+ Node* const rhs_hi_word = Float64ExtractHighWord32(rhs_float);
+
+ // If x is +0 and y is -0, return false.
+ // If x is -0 and y is +0, return false.
+
+ Node* const result = Word32Equal(lhs_hi_word, rhs_hi_word);
+ var_result.Bind(result);
+ Goto(&out);
+ }
+
+ Bind(&if_floatnotequal);
+ {
+ var_result.Bind(int_false);
+ Goto(&out);
+ }
+ }
+ }
+
+ Bind(&strict_equal);
+ {
+ Node* const is_equal = StrictEqual(kDontNegateResult, lhs, rhs, context);
+ Node* const result = WordEqual(is_equal, TrueConstant());
+ var_result.Bind(result);
+ Goto(&out);
+ }
+
+ Bind(&out);
+ return var_result.value();
+}
+
compiler::Node* CodeStubAssembler::ForInFilter(compiler::Node* key,
compiler::Node* object,
compiler::Node* context) {
« no previous file with comments | « src/code-stub-assembler.h ('k') | test/mjsunit/regexp.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698