| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 // static | 196 // static |
| 197 MaybeHandle<Name> Object::ConvertToName(Isolate* isolate, | 197 MaybeHandle<Name> Object::ConvertToName(Isolate* isolate, |
| 198 Handle<Object> input) { | 198 Handle<Object> input) { |
| 199 ASSIGN_RETURN_ON_EXCEPTION( | 199 ASSIGN_RETURN_ON_EXCEPTION( |
| 200 isolate, input, Object::ToPrimitive(input, ToPrimitiveHint::kString), | 200 isolate, input, Object::ToPrimitive(input, ToPrimitiveHint::kString), |
| 201 Name); | 201 Name); |
| 202 if (input->IsName()) return Handle<Name>::cast(input); | 202 if (input->IsName()) return Handle<Name>::cast(input); |
| 203 return ToString(isolate, input); | 203 return ToString(isolate, input); |
| 204 } | 204 } |
| 205 | 205 |
| 206 // ES6 7.1.14 | |
| 207 // static | |
| 208 MaybeHandle<Object> Object::ConvertToPropertyKey(Isolate* isolate, | |
| 209 Handle<Object> value) { | |
| 210 // 1. Let key be ToPrimitive(argument, hint String). | |
| 211 MaybeHandle<Object> maybe_key = | |
| 212 Object::ToPrimitive(value, ToPrimitiveHint::kString); | |
| 213 // 2. ReturnIfAbrupt(key). | |
| 214 Handle<Object> key; | |
| 215 if (!maybe_key.ToHandle(&key)) return key; | |
| 216 // 3. If Type(key) is Symbol, then return key. | |
| 217 if (key->IsSymbol()) return key; | |
| 218 // 4. Return ToString(key). | |
| 219 // Extending spec'ed behavior, we'd be happy to return an element index. | |
| 220 if (key->IsSmi()) return key; | |
| 221 if (key->IsHeapNumber()) { | |
| 222 uint32_t uint_value; | |
| 223 if (value->ToArrayLength(&uint_value) && | |
| 224 uint_value <= static_cast<uint32_t>(Smi::kMaxValue)) { | |
| 225 return handle(Smi::FromInt(static_cast<int>(uint_value)), isolate); | |
| 226 } | |
| 227 } | |
| 228 return Object::ToString(isolate, key); | |
| 229 } | |
| 230 | |
| 231 // static | 206 // static |
| 232 MaybeHandle<String> Object::ConvertToString(Isolate* isolate, | 207 MaybeHandle<String> Object::ConvertToString(Isolate* isolate, |
| 233 Handle<Object> input) { | 208 Handle<Object> input) { |
| 234 while (true) { | 209 while (true) { |
| 235 if (input->IsOddball()) { | 210 if (input->IsOddball()) { |
| 236 return handle(Handle<Oddball>::cast(input)->to_string(), isolate); | 211 return handle(Handle<Oddball>::cast(input)->to_string(), isolate); |
| 237 } | 212 } |
| 238 if (input->IsNumber()) { | 213 if (input->IsNumber()) { |
| 239 return isolate->factory()->NumberToString(input); | 214 return isolate->factory()->NumberToString(input); |
| 240 } | 215 } |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 | 376 |
| 402 IncrementalStringBuilder builder(isolate); | 377 IncrementalStringBuilder builder(isolate); |
| 403 builder.AppendCString("[object "); | 378 builder.AppendCString("[object "); |
| 404 builder.AppendString(tag); | 379 builder.AppendString(tag); |
| 405 builder.AppendCString("]"); | 380 builder.AppendCString("]"); |
| 406 | 381 |
| 407 return builder.Finish().ToHandleChecked(); | 382 return builder.Finish().ToHandleChecked(); |
| 408 } | 383 } |
| 409 | 384 |
| 410 // static | 385 // static |
| 411 MaybeHandle<Object> Object::ConvertToLength(Isolate* isolate, | 386 MaybeHandle<Object> Object::ToLength(Isolate* isolate, Handle<Object> input) { |
| 412 Handle<Object> input) { | |
| 413 ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object); | 387 ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object); |
| 414 if (input->IsSmi()) { | |
| 415 int value = std::max(Smi::cast(*input)->value(), 0); | |
| 416 return handle(Smi::FromInt(value), isolate); | |
| 417 } | |
| 418 double len = DoubleToInteger(input->Number()); | 388 double len = DoubleToInteger(input->Number()); |
| 419 if (len <= 0.0) { | 389 if (len <= 0.0) { |
| 420 return handle(Smi::kZero, isolate); | 390 len = 0.0; |
| 421 } else if (len >= kMaxSafeInteger) { | 391 } else if (len >= kMaxSafeInteger) { |
| 422 len = kMaxSafeInteger; | 392 len = kMaxSafeInteger; |
| 423 } | 393 } |
| 424 return isolate->factory()->NewNumber(len); | 394 return isolate->factory()->NewNumber(len); |
| 425 } | 395 } |
| 426 | 396 |
| 427 // static | 397 // static |
| 428 MaybeHandle<Object> Object::ConvertToIndex( | 398 MaybeHandle<Object> Object::ToIndex(Isolate* isolate, Handle<Object> input, |
| 429 Isolate* isolate, Handle<Object> input, | 399 MessageTemplate::Template error_index) { |
| 430 MessageTemplate::Template error_index) { | 400 if (input->IsUndefined(isolate)) return isolate->factory()->NewNumber(0.0); |
| 431 if (input->IsUndefined(isolate)) return handle(Smi::kZero, isolate); | |
| 432 ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object); | 401 ASSIGN_RETURN_ON_EXCEPTION(isolate, input, ToNumber(input), Object); |
| 433 if (input->IsSmi() && Smi::cast(*input)->value() >= 0) return input; | |
| 434 double len = DoubleToInteger(input->Number()) + 0.0; | 402 double len = DoubleToInteger(input->Number()) + 0.0; |
| 435 auto js_len = isolate->factory()->NewNumber(len); | 403 auto js_len = isolate->factory()->NewNumber(len); |
| 436 if (len < 0.0 || len > kMaxSafeInteger) { | 404 if (len < 0.0 || len > kMaxSafeInteger) { |
| 437 THROW_NEW_ERROR(isolate, NewRangeError(error_index, js_len), Object); | 405 THROW_NEW_ERROR(isolate, NewRangeError(error_index, js_len), Object); |
| 438 } | 406 } |
| 439 return js_len; | 407 return js_len; |
| 440 } | 408 } |
| 441 | 409 |
| 442 bool Object::BooleanValue() { | 410 bool Object::BooleanValue() { |
| 443 if (IsSmi()) return Smi::cast(this)->value() != 0; | 411 if (IsSmi()) return Smi::cast(this)->value() != 0; |
| (...skipping 6074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6518 | 6486 |
| 6519 | 6487 |
| 6520 Maybe<bool> JSReceiver::DeletePropertyOrElement(Handle<JSReceiver> object, | 6488 Maybe<bool> JSReceiver::DeletePropertyOrElement(Handle<JSReceiver> object, |
| 6521 Handle<Name> name, | 6489 Handle<Name> name, |
| 6522 LanguageMode language_mode) { | 6490 LanguageMode language_mode) { |
| 6523 LookupIterator it = LookupIterator::PropertyOrElement( | 6491 LookupIterator it = LookupIterator::PropertyOrElement( |
| 6524 name->GetIsolate(), object, name, object, LookupIterator::OWN); | 6492 name->GetIsolate(), object, name, object, LookupIterator::OWN); |
| 6525 return DeleteProperty(&it, language_mode); | 6493 return DeleteProperty(&it, language_mode); |
| 6526 } | 6494 } |
| 6527 | 6495 |
| 6496 |
| 6497 // ES6 7.1.14 |
| 6498 // static |
| 6499 MaybeHandle<Object> Object::ToPropertyKey(Isolate* isolate, |
| 6500 Handle<Object> value) { |
| 6501 // 1. Let key be ToPrimitive(argument, hint String). |
| 6502 MaybeHandle<Object> maybe_key = |
| 6503 Object::ToPrimitive(value, ToPrimitiveHint::kString); |
| 6504 // 2. ReturnIfAbrupt(key). |
| 6505 Handle<Object> key; |
| 6506 if (!maybe_key.ToHandle(&key)) return key; |
| 6507 // 3. If Type(key) is Symbol, then return key. |
| 6508 if (key->IsSymbol()) return key; |
| 6509 // 4. Return ToString(key). |
| 6510 // Extending spec'ed behavior, we'd be happy to return an element index. |
| 6511 if (key->IsSmi()) return key; |
| 6512 if (key->IsHeapNumber()) { |
| 6513 uint32_t uint_value; |
| 6514 if (value->ToArrayLength(&uint_value) && |
| 6515 uint_value <= static_cast<uint32_t>(Smi::kMaxValue)) { |
| 6516 return handle(Smi::FromInt(static_cast<int>(uint_value)), isolate); |
| 6517 } |
| 6518 } |
| 6519 return Object::ToString(isolate, key); |
| 6520 } |
| 6521 |
| 6522 |
| 6528 // ES6 19.1.2.4 | 6523 // ES6 19.1.2.4 |
| 6529 // static | 6524 // static |
| 6530 Object* JSReceiver::DefineProperty(Isolate* isolate, Handle<Object> object, | 6525 Object* JSReceiver::DefineProperty(Isolate* isolate, Handle<Object> object, |
| 6531 Handle<Object> key, | 6526 Handle<Object> key, |
| 6532 Handle<Object> attributes) { | 6527 Handle<Object> attributes) { |
| 6533 // 1. If Type(O) is not Object, throw a TypeError exception. | 6528 // 1. If Type(O) is not Object, throw a TypeError exception. |
| 6534 if (!object->IsJSReceiver()) { | 6529 if (!object->IsJSReceiver()) { |
| 6535 Handle<String> fun_name = | 6530 Handle<String> fun_name = |
| 6536 isolate->factory()->InternalizeUtf8String("Object.defineProperty"); | 6531 isolate->factory()->InternalizeUtf8String("Object.defineProperty"); |
| 6537 THROW_NEW_ERROR_RETURN_FAILURE( | 6532 THROW_NEW_ERROR_RETURN_FAILURE( |
| (...skipping 13907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 20445 // depend on this. | 20440 // depend on this. |
| 20446 return DICTIONARY_ELEMENTS; | 20441 return DICTIONARY_ELEMENTS; |
| 20447 } | 20442 } |
| 20448 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 20443 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
| 20449 return kind; | 20444 return kind; |
| 20450 } | 20445 } |
| 20451 } | 20446 } |
| 20452 | 20447 |
| 20453 } // namespace internal | 20448 } // namespace internal |
| 20454 } // namespace v8 | 20449 } // namespace v8 |
| OLD | NEW |