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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath>
7 #include <iomanip> 8 #include <iomanip>
8 #include <sstream> 9 #include <sstream>
9 10
10 #include "src/accessors.h" 11 #include "src/accessors.h"
11 #include "src/allocation-site-scopes.h" 12 #include "src/allocation-site-scopes.h"
12 #include "src/api.h" 13 #include "src/api.h"
13 #include "src/arguments.h" 14 #include "src/arguments.h"
14 #include "src/base/bits.h" 15 #include "src/base/bits.h"
15 #include "src/base/utils/random-number-generator.h" 16 #include "src/base/utils/random-number-generator.h"
16 #include "src/bootstrapper.h" 17 #include "src/bootstrapper.h"
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 if (IsString()) return String::cast(this)->length() != 0; 157 if (IsString()) return String::cast(this)->length() != 0;
157 if (IsHeapNumber()) return HeapNumber::cast(this)->HeapNumberBooleanValue(); 158 if (IsHeapNumber()) return HeapNumber::cast(this)->HeapNumberBooleanValue();
158 return true; 159 return true;
159 } 160 }
160 161
161 162
162 namespace { 163 namespace {
163 164
164 // TODO(bmeurer): Maybe we should introduce a marker interface Number, 165 // TODO(bmeurer): Maybe we should introduce a marker interface Number,
165 // where we put all these methods at some point? 166 // where we put all these methods at some point?
167 ComparisonResult NumberCompare(double x, double y) {
168 if (std::isnan(x) || std::isnan(y)) {
169 return ComparisonResult::kUndefined;
170 } else if (x < y) {
171 return ComparisonResult::kLessThan;
172 } else if (x > y) {
173 return ComparisonResult::kGreaterThan;
174 } else {
175 return ComparisonResult::kEqual;
176 }
177 }
178
179
166 bool NumberEquals(double x, double y) { 180 bool NumberEquals(double x, double y) {
167 // Must check explicitly for NaN's on Windows, but -0 works fine. 181 // Must check explicitly for NaN's on Windows, but -0 works fine.
168 if (std::isnan(x)) return false; 182 if (std::isnan(x)) return false;
169 if (std::isnan(y)) return false; 183 if (std::isnan(y)) return false;
170 return x == y; 184 return x == y;
171 } 185 }
172 186
173 187
174 bool NumberEquals(const Object* x, const Object* y) { 188 bool NumberEquals(const Object* x, const Object* y) {
175 return NumberEquals(x->Number(), y->Number()); 189 return NumberEquals(x->Number(), y->Number());
176 } 190 }
177 191
178 192
179 bool NumberEquals(Handle<Object> x, Handle<Object> y) { 193 bool NumberEquals(Handle<Object> x, Handle<Object> y) {
180 return NumberEquals(*x, *y); 194 return NumberEquals(*x, *y);
181 } 195 }
182 196
183 } // namespace 197 } // namespace
184 198
185 199
186 // static 200 // static
201 Maybe<ComparisonResult> Object::Compare(Handle<Object> x, Handle<Object> y,
202 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
203 if (!is_strong(strength)) {
204 // ES6 section 7.2.11 Abstract Relational Comparison step 3 and 4.
205 if (!Object::ToPrimitive(x, ToPrimitiveHint::kNumber).ToHandle(&x) ||
206 !Object::ToPrimitive(y, ToPrimitiveHint::kNumber).ToHandle(&y)) {
207 return Nothing<ComparisonResult>();
208 }
209 }
210 if (x->IsString() && y->IsString()) {
211 // ES6 section 7.2.11 Abstract Relational Comparison step 5.
212 return Just(
213 String::Compare(Handle<String>::cast(x), Handle<String>::cast(y)));
214 }
215 // ES6 section 7.2.11 Abstract Relational Comparison step 6.
216 if (!is_strong(strength)) {
217 if (!Object::ToNumber(x).ToHandle(&x) ||
218 !Object::ToNumber(y).ToHandle(&y)) {
219 return Nothing<ComparisonResult>();
220 }
221 } else {
222 if (!x->IsNumber()) {
223 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
224 isolate->Throw(*isolate->factory()->NewTypeError(
225 MessageTemplate::kStrongImplicitConversion));
226 return Nothing<ComparisonResult>();
227 } else if (!y->IsNumber()) {
228 Isolate* const isolate = Handle<HeapObject>::cast(y)->GetIsolate();
229 isolate->Throw(*isolate->factory()->NewTypeError(
230 MessageTemplate::kStrongImplicitConversion));
231 return Nothing<ComparisonResult>();
232 }
233 }
234 return Just(NumberCompare(x->Number(), y->Number()));
235 }
236
237
238 // static
187 Maybe<bool> Object::Equals(Handle<Object> x, Handle<Object> y) { 239 Maybe<bool> Object::Equals(Handle<Object> x, Handle<Object> y) {
188 while (true) { 240 while (true) {
189 if (x->IsNumber()) { 241 if (x->IsNumber()) {
190 if (y->IsNumber()) { 242 if (y->IsNumber()) {
191 return Just(NumberEquals(x, y)); 243 return Just(NumberEquals(x, y));
192 } else if (y->IsBoolean()) { 244 } else if (y->IsBoolean()) {
193 return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number())); 245 return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number()));
194 } else if (y->IsString()) { 246 } else if (y->IsString()) {
195 return Just(NumberEquals(x, String::ToNumber(Handle<String>::cast(y)))); 247 return Just(NumberEquals(x, String::ToNumber(Handle<String>::cast(y))));
196 } else if (y->IsJSReceiver() && !y->IsUndetectableObject()) { 248 } else if (y->IsJSReceiver() && !y->IsUndetectableObject()) {
(...skipping 9399 matching lines...) Expand 10 before | Expand all | Expand 10 after
9596 one_length); 9648 one_length);
9597 } else { 9649 } else {
9598 for (int i = 0; i < one_length; i++) { 9650 for (int i = 0; i < one_length; i++) {
9599 if (flat1.Get(i) != flat2.Get(i)) return false; 9651 if (flat1.Get(i) != flat2.Get(i)) return false;
9600 } 9652 }
9601 return true; 9653 return true;
9602 } 9654 }
9603 } 9655 }
9604 9656
9605 9657
9658 // static
9659 ComparisonResult String::Compare(Handle<String> x, Handle<String> y) {
9660 // A few fast case tests before we flatten.
9661 if (x.is_identical_to(y)) {
9662 return ComparisonResult::kEqual;
9663 } else if (y->length() == 0) {
9664 return x->length() == 0 ? ComparisonResult::kEqual
9665 : ComparisonResult::kGreaterThan;
9666 } else if (x->length() == 0) {
9667 return ComparisonResult::kLessThan;
9668 }
9669
9670 int const d = x->Get(0) - y->Get(0);
9671 if (d < 0) {
9672 return ComparisonResult::kLessThan;
9673 } else if (d > 0) {
9674 return ComparisonResult::kGreaterThan;
9675 }
9676
9677 // Slow case.
9678 x = String::Flatten(x);
9679 y = String::Flatten(y);
9680
9681 DisallowHeapAllocation no_gc;
9682 ComparisonResult result = ComparisonResult::kEqual;
9683 int prefix_length = x->length();
9684 if (y->length() < prefix_length) {
9685 prefix_length = y->length();
9686 result = ComparisonResult::kGreaterThan;
9687 } else if (y->length() > prefix_length) {
9688 result = ComparisonResult::kLessThan;
9689 }
9690 int r;
9691 String::FlatContent x_content = x->GetFlatContent();
9692 String::FlatContent y_content = y->GetFlatContent();
9693 if (x_content.IsOneByte()) {
9694 Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
9695 if (y_content.IsOneByte()) {
9696 Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
9697 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
9698 } else {
9699 Vector<const uc16> y_chars = y_content.ToUC16Vector();
9700 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
9701 }
9702 } else {
9703 Vector<const uc16> x_chars = x_content.ToUC16Vector();
9704 if (y_content.IsOneByte()) {
9705 Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
9706 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
9707 } else {
9708 Vector<const uc16> y_chars = y_content.ToUC16Vector();
9709 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
9710 }
9711 }
9712 if (r < 0) {
9713 result = ComparisonResult::kLessThan;
9714 } else if (r > 0) {
9715 result = ComparisonResult::kGreaterThan;
9716 }
9717 return result;
9718 }
9719
9720
9606 bool String::IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match) { 9721 bool String::IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match) {
9607 int slen = length(); 9722 int slen = length();
9608 // Can't check exact length equality, but we can check bounds. 9723 // Can't check exact length equality, but we can check bounds.
9609 int str_len = str.length(); 9724 int str_len = str.length();
9610 if (!allow_prefix_match && 9725 if (!allow_prefix_match &&
9611 (str_len < slen || 9726 (str_len < slen ||
9612 str_len > slen*static_cast<int>(unibrow::Utf8::kMaxEncodedSize))) { 9727 str_len > slen*static_cast<int>(unibrow::Utf8::kMaxEncodedSize))) {
9613 return false; 9728 return false;
9614 } 9729 }
9615 int i; 9730 int i;
(...skipping 6959 matching lines...) Expand 10 before | Expand all | Expand 10 after
16575 if (cell->value() != *new_value) { 16690 if (cell->value() != *new_value) {
16576 cell->set_value(*new_value); 16691 cell->set_value(*new_value);
16577 Isolate* isolate = cell->GetIsolate(); 16692 Isolate* isolate = cell->GetIsolate();
16578 cell->dependent_code()->DeoptimizeDependentCodeGroup( 16693 cell->dependent_code()->DeoptimizeDependentCodeGroup(
16579 isolate, DependentCode::kPropertyCellChangedGroup); 16694 isolate, DependentCode::kPropertyCellChangedGroup);
16580 } 16695 }
16581 } 16696 }
16582 16697
16583 } // namespace internal 16698 } // namespace internal
16584 } // namespace v8 16699 } // namespace v8
OLDNEW
« 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