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

Unified Diff: src/objects.cc

Issue 1350113002: [runtime] Replace COMPARE/COMPARE_STRONG with proper Object::Compare. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 4fa1b68496fd7e1ab6563064d218edb45ec12c60..7db54aa811e7ce2ed260f4ec729675231fd830bd 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -4,6 +4,7 @@
#include "src/objects.h"
+#include <cmath>
#include <iomanip>
#include <sstream>
@@ -163,6 +164,19 @@ namespace {
// TODO(bmeurer): Maybe we should introduce a marker interface Number,
// where we put all these methods at some point?
+ComparisonResult NumberCompare(double x, double y) {
+ if (std::isnan(x) || std::isnan(y)) {
+ return ComparisonResult::kUndefined;
+ } else if (x < y) {
+ return ComparisonResult::kLessThan;
+ } else if (x > y) {
+ return ComparisonResult::kGreaterThan;
+ } else {
+ return ComparisonResult::kEqual;
+ }
+}
+
+
bool NumberEquals(double x, double y) {
// Must check explicitly for NaN's on Windows, but -0 works fine.
if (std::isnan(x)) return false;
@@ -184,6 +198,44 @@ bool NumberEquals(Handle<Object> x, Handle<Object> y) {
// static
+Maybe<ComparisonResult> Object::Compare(Handle<Object> x, Handle<Object> y,
+ Strength strength) {
conradw 2015/09/18 08:59:22 We've been trying to use the Strength enum only fo
Benedikt Meurer 2015/09/18 09:52:03 Hm, that was totally non obvious from the comment
+ if (!is_strong(strength)) {
+ // ES6 section 7.2.11 Abstract Relational Comparison step 3 and 4.
+ if (!Object::ToPrimitive(x, ToPrimitiveHint::kNumber).ToHandle(&x) ||
+ !Object::ToPrimitive(y, ToPrimitiveHint::kNumber).ToHandle(&y)) {
+ return Nothing<ComparisonResult>();
+ }
+ }
+ if (x->IsString() && y->IsString()) {
+ // ES6 section 7.2.11 Abstract Relational Comparison step 5.
+ return Just(
+ String::Compare(Handle<String>::cast(x), Handle<String>::cast(y)));
+ }
+ // ES6 section 7.2.11 Abstract Relational Comparison step 6.
+ if (!is_strong(strength)) {
+ if (!Object::ToNumber(x).ToHandle(&x) ||
+ !Object::ToNumber(y).ToHandle(&y)) {
+ return Nothing<ComparisonResult>();
+ }
+ } else {
+ if (!x->IsNumber()) {
+ Isolate* const isolate = Handle<HeapObject>::cast(x)->GetIsolate();
conradw 2015/09/18 08:59:22 Can the isolates ever be different here?
Benedikt Meurer 2015/09/18 09:52:03 No, but either x or y can be a Smi and therefore t
+ isolate->Throw(*isolate->factory()->NewTypeError(
+ MessageTemplate::kStrongImplicitConversion));
+ return Nothing<ComparisonResult>();
+ } else if (!y->IsNumber()) {
+ Isolate* const isolate = Handle<HeapObject>::cast(y)->GetIsolate();
+ isolate->Throw(*isolate->factory()->NewTypeError(
+ MessageTemplate::kStrongImplicitConversion));
+ return Nothing<ComparisonResult>();
+ }
+ }
+ return Just(NumberCompare(x->Number(), y->Number()));
+}
+
+
+// static
Maybe<bool> Object::Equals(Handle<Object> x, Handle<Object> y) {
while (true) {
if (x->IsNumber()) {
@@ -9603,6 +9655,69 @@ bool String::SlowEquals(Handle<String> one, Handle<String> two) {
}
+// static
+ComparisonResult String::Compare(Handle<String> x, Handle<String> y) {
+ // A few fast case tests before we flatten.
+ if (x.is_identical_to(y)) {
+ return ComparisonResult::kEqual;
+ } else if (y->length() == 0) {
+ return x->length() == 0 ? ComparisonResult::kEqual
+ : ComparisonResult::kGreaterThan;
+ } else if (x->length() == 0) {
+ return ComparisonResult::kLessThan;
+ }
+
+ int const d = x->Get(0) - y->Get(0);
+ if (d < 0) {
+ return ComparisonResult::kLessThan;
+ } else if (d > 0) {
+ return ComparisonResult::kGreaterThan;
+ }
+
+ // Slow case.
+ x = String::Flatten(x);
+ y = String::Flatten(y);
+
+ DisallowHeapAllocation no_gc;
+ ComparisonResult result = ComparisonResult::kEqual;
+ int prefix_length = x->length();
+ if (y->length() < prefix_length) {
+ prefix_length = y->length();
+ result = ComparisonResult::kGreaterThan;
+ } else if (y->length() > prefix_length) {
+ result = ComparisonResult::kLessThan;
+ }
+ int r;
+ String::FlatContent x_content = x->GetFlatContent();
+ String::FlatContent y_content = y->GetFlatContent();
+ if (x_content.IsOneByte()) {
+ Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
+ if (y_content.IsOneByte()) {
+ Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
+ r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
+ } else {
+ Vector<const uc16> y_chars = y_content.ToUC16Vector();
+ r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
+ }
+ } else {
+ Vector<const uc16> x_chars = x_content.ToUC16Vector();
+ if (y_content.IsOneByte()) {
+ Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
+ r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
+ } else {
+ Vector<const uc16> y_chars = y_content.ToUC16Vector();
+ r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
+ }
+ }
+ if (r < 0) {
+ result = ComparisonResult::kLessThan;
+ } else if (r > 0) {
+ result = ComparisonResult::kGreaterThan;
+ }
+ return result;
+}
+
+
bool String::IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match) {
int slen = length();
// Can't check exact length equality, but we can check bounds.
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698