OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/builtins.h" | 5 #include "src/builtins.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/api-natives.h" | 8 #include "src/api-natives.h" |
9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 | 345 |
346 | 346 |
347 BUILTIN(Illegal) { | 347 BUILTIN(Illegal) { |
348 UNREACHABLE(); | 348 UNREACHABLE(); |
349 return isolate->heap()->undefined_value(); // Make compiler happy. | 349 return isolate->heap()->undefined_value(); // Make compiler happy. |
350 } | 350 } |
351 | 351 |
352 | 352 |
353 BUILTIN(EmptyFunction) { return isolate->heap()->undefined_value(); } | 353 BUILTIN(EmptyFunction) { return isolate->heap()->undefined_value(); } |
354 | 354 |
| 355 // ES6 7.3.11 |
| 356 BUILTIN(ObjectHasOwnProperty) { |
| 357 HandleScope scope(isolate); |
| 358 |
| 359 Handle<Object> property = args.atOrUndefined(isolate, 1); |
| 360 |
| 361 Handle<Name> key; |
| 362 uint32_t index; |
| 363 bool key_is_array_index = property->ToArrayIndex(&index); |
| 364 |
| 365 if (!key_is_array_index) { |
| 366 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key, |
| 367 Object::ToName(isolate, property)); |
| 368 key_is_array_index = key->AsArrayIndex(&index); |
| 369 } |
| 370 |
| 371 Handle<Object> object = args.receiver(); |
| 372 |
| 373 if (object->IsJSObject()) { |
| 374 Handle<JSObject> js_obj = Handle<JSObject>::cast(object); |
| 375 // Fast case: either the key is a real named property or it is not |
| 376 // an array index and there are no interceptors or hidden |
| 377 // prototypes. |
| 378 // TODO(jkummerow): Make JSReceiver::HasOwnProperty fast enough to |
| 379 // handle all cases directly (without this custom fast path). |
| 380 { |
| 381 LookupIterator::Configuration c = LookupIterator::OWN_SKIP_INTERCEPTOR; |
| 382 LookupIterator it = key_is_array_index |
| 383 ? LookupIterator(isolate, js_obj, index, c) |
| 384 : LookupIterator(js_obj, key, c); |
| 385 Maybe<bool> maybe = JSReceiver::HasProperty(&it); |
| 386 if (maybe.IsNothing()) return isolate->heap()->exception(); |
| 387 DCHECK(!isolate->has_pending_exception()); |
| 388 if (maybe.FromJust()) return isolate->heap()->true_value(); |
| 389 } |
| 390 |
| 391 Map* map = js_obj->map(); |
| 392 if (!map->has_hidden_prototype() && |
| 393 (key_is_array_index ? !map->has_indexed_interceptor() |
| 394 : !map->has_named_interceptor())) { |
| 395 return isolate->heap()->false_value(); |
| 396 } |
| 397 |
| 398 // Slow case. |
| 399 LookupIterator::Configuration c = LookupIterator::HIDDEN; |
| 400 LookupIterator it = key_is_array_index |
| 401 ? LookupIterator(isolate, js_obj, index, c) |
| 402 : LookupIterator(js_obj, key, c); |
| 403 |
| 404 Maybe<bool> maybe = JSReceiver::HasProperty(&it); |
| 405 if (maybe.IsNothing()) return isolate->heap()->exception(); |
| 406 DCHECK(!isolate->has_pending_exception()); |
| 407 return isolate->heap()->ToBoolean(maybe.FromJust()); |
| 408 |
| 409 } else if (object->IsJSProxy()) { |
| 410 if (key.is_null()) { |
| 411 DCHECK(key_is_array_index); |
| 412 key = isolate->factory()->Uint32ToString(index); |
| 413 } |
| 414 |
| 415 Maybe<bool> result = |
| 416 JSReceiver::HasOwnProperty(Handle<JSProxy>::cast(object), key); |
| 417 if (!result.IsJust()) return isolate->heap()->exception(); |
| 418 return isolate->heap()->ToBoolean(result.FromJust()); |
| 419 |
| 420 } else if (object->IsString()) { |
| 421 return isolate->heap()->ToBoolean( |
| 422 key_is_array_index |
| 423 ? index < static_cast<uint32_t>(String::cast(*object)->length()) |
| 424 : key->Equals(isolate->heap()->length_string())); |
| 425 } else if (object->IsNull() || object->IsUndefined()) { |
| 426 THROW_NEW_ERROR_RETURN_FAILURE( |
| 427 isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject)); |
| 428 } |
| 429 |
| 430 return isolate->heap()->false_value(); |
| 431 } |
355 | 432 |
356 BUILTIN(ArrayPush) { | 433 BUILTIN(ArrayPush) { |
357 HandleScope scope(isolate); | 434 HandleScope scope(isolate); |
358 Handle<Object> receiver = args.receiver(); | 435 Handle<Object> receiver = args.receiver(); |
359 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1)) { | 436 if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1)) { |
360 return CallJsIntrinsic(isolate, isolate->array_push(), args); | 437 return CallJsIntrinsic(isolate, isolate->array_push(), args); |
361 } | 438 } |
362 // Fast Elements Path | 439 // Fast Elements Path |
363 int push_size = args.length() - 1; | 440 int push_size = args.length() - 1; |
364 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 441 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
(...skipping 4142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4507 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 4584 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
4508 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 4585 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
4509 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 4586 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
4510 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 4587 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
4511 #undef DEFINE_BUILTIN_ACCESSOR_C | 4588 #undef DEFINE_BUILTIN_ACCESSOR_C |
4512 #undef DEFINE_BUILTIN_ACCESSOR_A | 4589 #undef DEFINE_BUILTIN_ACCESSOR_A |
4513 | 4590 |
4514 | 4591 |
4515 } // namespace internal | 4592 } // namespace internal |
4516 } // namespace v8 | 4593 } // namespace v8 |
OLD | NEW |