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

Side by Side Diff: src/objects.cc

Issue 1337993005: [runtime] Replace the EQUALS builtin with proper Object::Equals. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address Michi's nit. 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 <iomanip> 7 #include <iomanip>
8 #include <sstream> 8 #include <sstream>
9 9
10 #include "src/accessors.h" 10 #include "src/accessors.h"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 return result; 91 return result;
92 } 92 }
93 93
94 94
95 // static 95 // static
96 MaybeHandle<Object> Object::ToNumber(Handle<Object> input) { 96 MaybeHandle<Object> Object::ToNumber(Handle<Object> input) {
97 while (true) { 97 while (true) {
98 if (input->IsNumber()) { 98 if (input->IsNumber()) {
99 return input; 99 return input;
100 } 100 }
101 Isolate* const isolate = Handle<HeapObject>::cast(input)->GetIsolate();
102 if (input->IsOddball()) {
103 return handle(Handle<Oddball>::cast(input)->to_number(), isolate);
104 }
105 if (input->IsString()) { 101 if (input->IsString()) {
106 return String::ToNumber(Handle<String>::cast(input)); 102 return String::ToNumber(Handle<String>::cast(input));
107 } 103 }
104 if (input->IsOddball()) {
105 return Oddball::ToNumber(Handle<Oddball>::cast(input));
106 }
107 Isolate* const isolate = Handle<HeapObject>::cast(input)->GetIsolate();
108 if (input->IsSymbol()) { 108 if (input->IsSymbol()) {
109 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToNumber), 109 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToNumber),
110 Object); 110 Object);
111 } 111 }
112 if (input->IsSimd128Value()) { 112 if (input->IsSimd128Value()) {
113 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSimdToNumber), 113 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSimdToNumber),
114 Object); 114 Object);
115 } 115 }
116 ASSIGN_RETURN_ON_EXCEPTION( 116 ASSIGN_RETURN_ON_EXCEPTION(
117 isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input), 117 isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 if (IsBoolean()) return IsTrue(); 152 if (IsBoolean()) return IsTrue();
153 if (IsSmi()) return Smi::cast(this)->value() != 0; 153 if (IsSmi()) return Smi::cast(this)->value() != 0;
154 if (IsUndefined() || IsNull()) return false; 154 if (IsUndefined() || IsNull()) return false;
155 if (IsUndetectableObject()) return false; // Undetectable object is false. 155 if (IsUndetectableObject()) return false; // Undetectable object is false.
156 if (IsString()) return String::cast(this)->length() != 0; 156 if (IsString()) return String::cast(this)->length() != 0;
157 if (IsHeapNumber()) return HeapNumber::cast(this)->HeapNumberBooleanValue(); 157 if (IsHeapNumber()) return HeapNumber::cast(this)->HeapNumberBooleanValue();
158 return true; 158 return true;
159 } 159 }
160 160
161 161
162 namespace {
163
164 // TODO(bmeurer): Maybe we should introduce a marker interface Number,
165 // where we put all these methods at some point?
166 bool NumberEquals(double x, double y) {
167 // Must check explicitly for NaN's on Windows, but -0 works fine.
168 if (std::isnan(x)) return false;
169 if (std::isnan(y)) return false;
170 return x == y;
171 }
172
173
174 bool NumberEquals(const Object* x, const Object* y) {
175 return NumberEquals(x->Number(), y->Number());
176 }
177
178
179 bool NumberEquals(Handle<Object> x, Handle<Object> y) {
180 return NumberEquals(*x, *y);
181 }
182
183 } // namespace
184
185
186 // static
187 Maybe<bool> Object::Equals(Handle<Object> x, Handle<Object> y) {
188 while (true) {
189 if (x->IsNumber()) {
190 if (y->IsNumber()) {
191 return Just(NumberEquals(x, y));
192 } else if (y->IsBoolean()) {
193 return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number()));
194 } else if (y->IsString()) {
195 return Just(NumberEquals(x, String::ToNumber(Handle<String>::cast(y))));
196 } else if (y->IsJSReceiver() && !y->IsUndetectableObject()) {
197 if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
198 .ToHandle(&y)) {
199 return Nothing<bool>();
200 }
201 } else {
202 return Just(false);
203 }
204 } else if (x->IsString()) {
205 if (y->IsString()) {
206 return Just(
207 String::Equals(Handle<String>::cast(x), Handle<String>::cast(y)));
208 } else if (y->IsNumber()) {
209 x = String::ToNumber(Handle<String>::cast(x));
210 return Just(NumberEquals(x, y));
211 } else if (y->IsBoolean()) {
212 x = String::ToNumber(Handle<String>::cast(x));
213 return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number()));
214 } else if (y->IsJSReceiver() && !y->IsUndetectableObject()) {
215 if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
216 .ToHandle(&y)) {
217 return Nothing<bool>();
218 }
219 } else {
220 return Just(false);
221 }
222 } else if (x->IsBoolean()) {
223 if (y->IsOddball()) {
224 return Just(x.is_identical_to(y));
225 } else if (y->IsNumber()) {
226 return Just(NumberEquals(Handle<Oddball>::cast(x)->to_number(), *y));
227 } else if (y->IsString()) {
228 y = String::ToNumber(Handle<String>::cast(y));
229 return Just(NumberEquals(Handle<Oddball>::cast(x)->to_number(), *y));
230 } else if (y->IsJSReceiver() && !y->IsUndetectableObject()) {
231 if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
232 .ToHandle(&y)) {
233 return Nothing<bool>();
234 }
235 x = Oddball::ToNumber(Handle<Oddball>::cast(x));
236 } else {
237 return Just(false);
238 }
239 } else if (x->IsSymbol()) {
240 return Just(x.is_identical_to(y));
241 } else if (x->IsSimd128Value()) {
242 if (!y->IsSimd128Value()) return Just(false);
243 return Just(Simd128Value::Equals(Handle<Simd128Value>::cast(x),
244 Handle<Simd128Value>::cast(y)));
245 } else if (x->IsJSReceiver() && !x->IsUndetectableObject()) {
246 if (y->IsJSReceiver()) {
247 return Just(x.is_identical_to(y));
248 } else if (y->IsNull() || y->IsSimd128Value() || y->IsSymbol() ||
249 y->IsUndefined()) {
250 return Just(false);
251 } else if (y->IsBoolean()) {
252 y = Oddball::ToNumber(Handle<Oddball>::cast(y));
253 }
254 if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(x)).ToHandle(&x)) {
255 return Nothing<bool>();
256 }
257 } else {
258 return Just(
259 (x->IsNull() || x->IsUndefined() || x->IsUndetectableObject()) &&
260 (y->IsNull() || y->IsUndefined() || y->IsUndetectableObject()));
261 }
262 }
263 }
264
265
162 bool Object::StrictEquals(Object* that) { 266 bool Object::StrictEquals(Object* that) {
163 if (this->IsNumber()) { 267 if (this->IsNumber()) {
164 if (!that->IsNumber()) return false; 268 if (!that->IsNumber()) return false;
165 double const x = this->Number(); 269 return NumberEquals(this, that);
166 double const y = that->Number();
167 // Must check explicitly for NaN:s on Windows, but -0 works fine.
168 return x == y && !std::isnan(x) && !std::isnan(y);
169 } else if (this->IsString()) { 270 } else if (this->IsString()) {
170 if (!that->IsString()) return false; 271 if (!that->IsString()) return false;
171 return String::cast(this)->Equals(String::cast(that)); 272 return String::cast(this)->Equals(String::cast(that));
172 } else if (this->IsSimd128Value()) { 273 } else if (this->IsSimd128Value()) {
173 if (!that->IsSimd128Value()) return false; 274 if (!that->IsSimd128Value()) return false;
174 return Simd128Value::cast(this)->Equals(Simd128Value::cast(that)); 275 return Simd128Value::cast(this)->Equals(Simd128Value::cast(that));
175 } 276 }
176 return this == that; 277 return this == that;
177 } 278 }
178 279
(...skipping 16184 matching lines...) Expand 10 before | Expand all | Expand 10 after
16363 if (cell->value() != *new_value) { 16464 if (cell->value() != *new_value) {
16364 cell->set_value(*new_value); 16465 cell->set_value(*new_value);
16365 Isolate* isolate = cell->GetIsolate(); 16466 Isolate* isolate = cell->GetIsolate();
16366 cell->dependent_code()->DeoptimizeDependentCodeGroup( 16467 cell->dependent_code()->DeoptimizeDependentCodeGroup(
16367 isolate, DependentCode::kPropertyCellChangedGroup); 16468 isolate, DependentCode::kPropertyCellChangedGroup);
16368 } 16469 }
16369 } 16470 }
16370 16471
16371 } // namespace internal 16472 } // namespace internal
16372 } // namespace v8 16473 } // 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