| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 Name* name_raw) { | 471 Name* name_raw) { |
| 472 Isolate* isolate = GetIsolate(); | 472 Isolate* isolate = GetIsolate(); |
| 473 HandleScope scope(isolate); | 473 HandleScope scope(isolate); |
| 474 Handle<Object> receiver(receiver_raw, isolate); | 474 Handle<Object> receiver(receiver_raw, isolate); |
| 475 Handle<Object> name(name_raw, isolate); | 475 Handle<Object> name(name_raw, isolate); |
| 476 | 476 |
| 477 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 477 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 478 if (name->IsSymbol()) return isolate->heap()->undefined_value(); | 478 if (name->IsSymbol()) return isolate->heap()->undefined_value(); |
| 479 | 479 |
| 480 Handle<Object> args[] = { receiver, name }; | 480 Handle<Object> args[] = { receiver, name }; |
| 481 Handle<Object> result = CallTrap( | 481 Handle<Object> result; |
| 482 "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args); | 482 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 483 if (isolate->has_pending_exception()) return Failure::Exception(); | 483 isolate, result, |
| 484 | 484 CallTrap(handle(this), |
| 485 "get", |
| 486 isolate->derived_get_trap(), |
| 487 ARRAY_SIZE(args), |
| 488 args)); |
| 485 return *result; | 489 return *result; |
| 486 } | 490 } |
| 487 | 491 |
| 488 | 492 |
| 489 Handle<Object> Object::GetPropertyOrElement(Handle<Object> object, | 493 Handle<Object> Object::GetPropertyOrElement(Handle<Object> object, |
| 490 Handle<Name> name) { | 494 Handle<Name> name) { |
| 491 uint32_t index; | 495 uint32_t index; |
| 492 Isolate* isolate = name->GetIsolate(); | 496 Isolate* isolate = name->GetIsolate(); |
| 493 if (name->AsArrayIndex(&index)) return GetElement(isolate, object, index); | 497 if (name->AsArrayIndex(&index)) return GetElement(isolate, object, index); |
| 494 return GetProperty(object, name); | 498 return GetProperty(object, name); |
| 495 } | 499 } |
| 496 | 500 |
| 497 | 501 |
| 498 Handle<Object> Object::GetProperty(Handle<Object> object, | 502 Handle<Object> Object::GetProperty(Handle<Object> object, |
| 499 Handle<Name> name) { | 503 Handle<Name> name) { |
| 500 CALL_HEAP_FUNCTION(name->GetIsolate(), object->GetProperty(*name), Object); | 504 CALL_HEAP_FUNCTION(name->GetIsolate(), object->GetProperty(*name), Object); |
| 501 } | 505 } |
| 502 | 506 |
| 503 | 507 |
| 504 MaybeObject* JSProxy::GetElementWithHandler(Object* receiver, | 508 MaybeObject* JSProxy::GetElementWithHandler(Object* receiver, |
| 505 uint32_t index) { | 509 uint32_t index) { |
| 506 String* name; | 510 String* name; |
| 507 MaybeObject* maybe = GetHeap()->Uint32ToString(index); | 511 MaybeObject* maybe = GetHeap()->Uint32ToString(index); |
| 508 if (!maybe->To<String>(&name)) return maybe; | 512 if (!maybe->To<String>(&name)) return maybe; |
| 509 return GetPropertyWithHandler(receiver, name); | 513 return GetPropertyWithHandler(receiver, name); |
| 510 } | 514 } |
| 511 | 515 |
| 512 | 516 |
| 513 Handle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy, | 517 MaybeHandle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy, |
| 514 Handle<JSReceiver> receiver, | 518 Handle<JSReceiver> receiver, |
| 515 uint32_t index, | 519 uint32_t index, |
| 516 Handle<Object> value, | 520 Handle<Object> value, |
| 517 StrictMode strict_mode) { | 521 StrictMode strict_mode) { |
| 518 Isolate* isolate = proxy->GetIsolate(); | 522 Isolate* isolate = proxy->GetIsolate(); |
| 519 Handle<String> name = isolate->factory()->Uint32ToString(index); | 523 Handle<String> name = isolate->factory()->Uint32ToString(index); |
| 520 return SetPropertyWithHandler( | 524 return SetPropertyWithHandler( |
| 521 proxy, receiver, name, value, NONE, strict_mode); | 525 proxy, receiver, name, value, NONE, strict_mode); |
| 522 } | 526 } |
| 523 | 527 |
| 524 | 528 |
| 525 bool JSProxy::HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index) { | 529 bool JSProxy::HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index) { |
| 526 Isolate* isolate = proxy->GetIsolate(); | 530 Isolate* isolate = proxy->GetIsolate(); |
| 527 Handle<String> name = isolate->factory()->Uint32ToString(index); | 531 Handle<String> name = isolate->factory()->Uint32ToString(index); |
| (...skipping 2467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2995 bool has_pending_exception; | 2999 bool has_pending_exception; |
| 2996 Handle<Object> argv[] = { value }; | 3000 Handle<Object> argv[] = { value }; |
| 2997 Execution::Call( | 3001 Execution::Call( |
| 2998 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception); | 3002 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception); |
| 2999 // Check for pending exception and return the result. | 3003 // Check for pending exception and return the result. |
| 3000 if (has_pending_exception) return Handle<Object>(); | 3004 if (has_pending_exception) return Handle<Object>(); |
| 3001 return value; | 3005 return value; |
| 3002 } | 3006 } |
| 3003 | 3007 |
| 3004 | 3008 |
| 3005 Handle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( | 3009 MaybeHandle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( |
| 3006 Handle<JSObject> object, | 3010 Handle<JSObject> object, |
| 3007 uint32_t index, | 3011 uint32_t index, |
| 3008 Handle<Object> value, | 3012 Handle<Object> value, |
| 3009 bool* found, | 3013 bool* found, |
| 3010 StrictMode strict_mode) { | 3014 StrictMode strict_mode) { |
| 3011 Isolate *isolate = object->GetIsolate(); | 3015 Isolate *isolate = object->GetIsolate(); |
| 3012 for (Handle<Object> proto = handle(object->GetPrototype(), isolate); | 3016 for (Handle<Object> proto = handle(object->GetPrototype(), isolate); |
| 3013 !proto->IsNull(); | 3017 !proto->IsNull(); |
| 3014 proto = handle(proto->GetPrototype(isolate), isolate)) { | 3018 proto = handle(proto->GetPrototype(isolate), isolate)) { |
| 3015 if (proto->IsJSProxy()) { | 3019 if (proto->IsJSProxy()) { |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3548 } | 3552 } |
| 3549 | 3553 |
| 3550 | 3554 |
| 3551 bool JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name) { | 3555 bool JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name) { |
| 3552 Isolate* isolate = proxy->GetIsolate(); | 3556 Isolate* isolate = proxy->GetIsolate(); |
| 3553 | 3557 |
| 3554 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3558 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 3555 if (name->IsSymbol()) return false; | 3559 if (name->IsSymbol()) return false; |
| 3556 | 3560 |
| 3557 Handle<Object> args[] = { name }; | 3561 Handle<Object> args[] = { name }; |
| 3558 Handle<Object> result = proxy->CallTrap( | 3562 Handle<Object> result; |
| 3559 "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args); | 3563 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 3560 if (isolate->has_pending_exception()) return false; | 3564 isolate, result, |
| 3565 CallTrap(proxy, |
| 3566 "has", |
| 3567 isolate->derived_has_trap(), |
| 3568 ARRAY_SIZE(args), |
| 3569 args), |
| 3570 false); |
| 3561 | 3571 |
| 3562 return result->BooleanValue(); | 3572 return result->BooleanValue(); |
| 3563 } | 3573 } |
| 3564 | 3574 |
| 3565 | 3575 |
| 3566 Handle<Object> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy, | 3576 MaybeHandle<Object> JSProxy::SetPropertyWithHandler( |
| 3567 Handle<JSReceiver> receiver, | 3577 Handle<JSProxy> proxy, |
| 3568 Handle<Name> name, | 3578 Handle<JSReceiver> receiver, |
| 3569 Handle<Object> value, | 3579 Handle<Name> name, |
| 3570 PropertyAttributes attributes, | 3580 Handle<Object> value, |
| 3571 StrictMode strict_mode) { | 3581 PropertyAttributes attributes, |
| 3582 StrictMode strict_mode) { |
| 3572 Isolate* isolate = proxy->GetIsolate(); | 3583 Isolate* isolate = proxy->GetIsolate(); |
| 3573 | 3584 |
| 3574 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3585 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 3575 if (name->IsSymbol()) return value; | 3586 if (name->IsSymbol()) return value; |
| 3576 | 3587 |
| 3577 Handle<Object> args[] = { receiver, name, value }; | 3588 Handle<Object> args[] = { receiver, name, value }; |
| 3578 proxy->CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); | 3589 RETURN_ON_EXCEPTION( |
| 3579 if (isolate->has_pending_exception()) return Handle<Object>(); | 3590 isolate, |
| 3591 CallTrap(proxy, |
| 3592 "set", |
| 3593 isolate->derived_set_trap(), |
| 3594 ARRAY_SIZE(args), |
| 3595 args), |
| 3596 Object); |
| 3580 | 3597 |
| 3581 return value; | 3598 return value; |
| 3582 } | 3599 } |
| 3583 | 3600 |
| 3584 | 3601 |
| 3585 Handle<Object> JSProxy::SetPropertyViaPrototypesWithHandler( | 3602 MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler( |
| 3586 Handle<JSProxy> proxy, | 3603 Handle<JSProxy> proxy, |
| 3587 Handle<JSReceiver> receiver, | 3604 Handle<JSReceiver> receiver, |
| 3588 Handle<Name> name, | 3605 Handle<Name> name, |
| 3589 Handle<Object> value, | 3606 Handle<Object> value, |
| 3590 PropertyAttributes attributes, | 3607 PropertyAttributes attributes, |
| 3591 StrictMode strict_mode, | 3608 StrictMode strict_mode, |
| 3592 bool* done) { | 3609 bool* done) { |
| 3593 Isolate* isolate = proxy->GetIsolate(); | 3610 Isolate* isolate = proxy->GetIsolate(); |
| 3594 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy. | 3611 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy. |
| 3595 | 3612 |
| 3596 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3613 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 3597 if (name->IsSymbol()) { | 3614 if (name->IsSymbol()) { |
| 3598 *done = false; | 3615 *done = false; |
| 3599 return isolate->factory()->the_hole_value(); | 3616 return isolate->factory()->the_hole_value(); |
| 3600 } | 3617 } |
| 3601 | 3618 |
| 3602 *done = true; // except where redefined... | 3619 *done = true; // except where redefined... |
| 3603 Handle<Object> args[] = { name }; | 3620 Handle<Object> args[] = { name }; |
| 3604 Handle<Object> result = proxy->CallTrap( | 3621 Handle<Object> result; |
| 3605 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); | 3622 ASSIGN_RETURN_ON_EXCEPTION( |
| 3606 if (isolate->has_pending_exception()) return Handle<Object>(); | 3623 isolate, result, |
| 3624 CallTrap(proxy, |
| 3625 "getPropertyDescriptor", |
| 3626 Handle<Object>(), |
| 3627 ARRAY_SIZE(args), |
| 3628 args), |
| 3629 Object); |
| 3607 | 3630 |
| 3608 if (result->IsUndefined()) { | 3631 if (result->IsUndefined()) { |
| 3609 *done = false; | 3632 *done = false; |
| 3610 return isolate->factory()->the_hole_value(); | 3633 return isolate->factory()->the_hole_value(); |
| 3611 } | 3634 } |
| 3612 | 3635 |
| 3613 // Emulate [[GetProperty]] semantics for proxies. | 3636 // Emulate [[GetProperty]] semantics for proxies. |
| 3614 bool has_pending_exception; | 3637 bool has_pending_exception; |
| 3615 Handle<Object> argv[] = { result }; | 3638 Handle<Object> argv[] = { result }; |
| 3616 Handle<Object> desc = Execution::Call( | 3639 Handle<Object> desc = Execution::Call( |
| 3617 isolate, isolate->to_complete_property_descriptor(), result, | 3640 isolate, isolate->to_complete_property_descriptor(), result, |
| 3618 ARRAY_SIZE(argv), argv, &has_pending_exception); | 3641 ARRAY_SIZE(argv), argv, &has_pending_exception); |
| 3619 if (has_pending_exception) return Handle<Object>(); | 3642 if (has_pending_exception) return MaybeHandle<Object>(); |
| 3620 | 3643 |
| 3621 // [[GetProperty]] requires to check that all properties are configurable. | 3644 // [[GetProperty]] requires to check that all properties are configurable. |
| 3622 Handle<String> configurable_name = | 3645 Handle<String> configurable_name = |
| 3623 isolate->factory()->InternalizeOneByteString( | 3646 isolate->factory()->InternalizeOneByteString( |
| 3624 STATIC_ASCII_VECTOR("configurable_")); | 3647 STATIC_ASCII_VECTOR("configurable_")); |
| 3625 Handle<Object> configurable = Object::GetProperty(desc, configurable_name); | 3648 Handle<Object> configurable = Object::GetProperty(desc, configurable_name); |
| 3626 ASSERT(!configurable.is_null()); | 3649 ASSERT(!configurable.is_null()); |
| 3627 ASSERT(configurable->IsTrue() || configurable->IsFalse()); | 3650 ASSERT(configurable->IsTrue() || configurable->IsFalse()); |
| 3628 if (configurable->IsFalse()) { | 3651 if (configurable->IsFalse()) { |
| 3629 Handle<String> trap = | 3652 Handle<String> trap = |
| 3630 isolate->factory()->InternalizeOneByteString( | 3653 isolate->factory()->InternalizeOneByteString( |
| 3631 STATIC_ASCII_VECTOR("getPropertyDescriptor")); | 3654 STATIC_ASCII_VECTOR("getPropertyDescriptor")); |
| 3632 Handle<Object> args[] = { handler, trap, name }; | 3655 Handle<Object> args[] = { handler, trap, name }; |
| 3633 Handle<Object> error = isolate->factory()->NewTypeError( | 3656 Handle<Object> error = isolate->factory()->NewTypeError( |
| 3634 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); | 3657 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); |
| 3635 isolate->Throw(*error); | 3658 return isolate->Throw<Object>(error); |
| 3636 return Handle<Object>(); | |
| 3637 } | 3659 } |
| 3638 ASSERT(configurable->IsTrue()); | 3660 ASSERT(configurable->IsTrue()); |
| 3639 | 3661 |
| 3640 // Check for DataDescriptor. | 3662 // Check for DataDescriptor. |
| 3641 Handle<String> hasWritable_name = | 3663 Handle<String> hasWritable_name = |
| 3642 isolate->factory()->InternalizeOneByteString( | 3664 isolate->factory()->InternalizeOneByteString( |
| 3643 STATIC_ASCII_VECTOR("hasWritable_")); | 3665 STATIC_ASCII_VECTOR("hasWritable_")); |
| 3644 Handle<Object> hasWritable = Object::GetProperty(desc, hasWritable_name); | 3666 Handle<Object> hasWritable = Object::GetProperty(desc, hasWritable_name); |
| 3645 ASSERT(!hasWritable.is_null()); | 3667 ASSERT(!hasWritable.is_null()); |
| 3646 ASSERT(hasWritable->IsTrue() || hasWritable->IsFalse()); | 3668 ASSERT(hasWritable->IsTrue() || hasWritable->IsFalse()); |
| 3647 if (hasWritable->IsTrue()) { | 3669 if (hasWritable->IsTrue()) { |
| 3648 Handle<String> writable_name = | 3670 Handle<String> writable_name = |
| 3649 isolate->factory()->InternalizeOneByteString( | 3671 isolate->factory()->InternalizeOneByteString( |
| 3650 STATIC_ASCII_VECTOR("writable_")); | 3672 STATIC_ASCII_VECTOR("writable_")); |
| 3651 Handle<Object> writable = Object::GetProperty(desc, writable_name); | 3673 Handle<Object> writable = Object::GetProperty(desc, writable_name); |
| 3652 ASSERT(!writable.is_null()); | 3674 ASSERT(!writable.is_null()); |
| 3653 ASSERT(writable->IsTrue() || writable->IsFalse()); | 3675 ASSERT(writable->IsTrue() || writable->IsFalse()); |
| 3654 *done = writable->IsFalse(); | 3676 *done = writable->IsFalse(); |
| 3655 if (!*done) return isolate->factory()->the_hole_value(); | 3677 if (!*done) return isolate->factory()->the_hole_value(); |
| 3656 if (strict_mode == SLOPPY) return value; | 3678 if (strict_mode == SLOPPY) return value; |
| 3657 Handle<Object> args[] = { name, receiver }; | 3679 Handle<Object> args[] = { name, receiver }; |
| 3658 Handle<Object> error = isolate->factory()->NewTypeError( | 3680 Handle<Object> error = isolate->factory()->NewTypeError( |
| 3659 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); | 3681 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); |
| 3660 isolate->Throw(*error); | 3682 return isolate->Throw<Object>(error); |
| 3661 return Handle<Object>(); | |
| 3662 } | 3683 } |
| 3663 | 3684 |
| 3664 // We have an AccessorDescriptor. | 3685 // We have an AccessorDescriptor. |
| 3665 Handle<String> set_name = isolate->factory()->InternalizeOneByteString( | 3686 Handle<String> set_name = isolate->factory()->InternalizeOneByteString( |
| 3666 STATIC_ASCII_VECTOR("set_")); | 3687 STATIC_ASCII_VECTOR("set_")); |
| 3667 Handle<Object> setter = Object::GetProperty(desc, set_name); | 3688 Handle<Object> setter = Object::GetProperty(desc, set_name); |
| 3668 ASSERT(!setter.is_null()); | 3689 ASSERT(!setter.is_null()); |
| 3669 if (!setter->IsUndefined()) { | 3690 if (!setter->IsUndefined()) { |
| 3670 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 3691 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
| 3671 return SetPropertyWithDefinedSetter( | 3692 return SetPropertyWithDefinedSetter( |
| 3672 receiver, Handle<JSReceiver>::cast(setter), value); | 3693 receiver, Handle<JSReceiver>::cast(setter), value); |
| 3673 } | 3694 } |
| 3674 | 3695 |
| 3675 if (strict_mode == SLOPPY) return value; | 3696 if (strict_mode == SLOPPY) return value; |
| 3676 Handle<Object> args2[] = { name, proxy }; | 3697 Handle<Object> args2[] = { name, proxy }; |
| 3677 Handle<Object> error = isolate->factory()->NewTypeError( | 3698 Handle<Object> error = isolate->factory()->NewTypeError( |
| 3678 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); | 3699 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); |
| 3679 isolate->Throw(*error); | 3700 return isolate->Throw<Object>(error); |
| 3680 return Handle<Object>(); | |
| 3681 } | 3701 } |
| 3682 | 3702 |
| 3683 | 3703 |
| 3684 Handle<Object> JSProxy::DeletePropertyWithHandler( | 3704 MaybeHandle<Object> JSProxy::DeletePropertyWithHandler( |
| 3685 Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) { | 3705 Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) { |
| 3686 Isolate* isolate = proxy->GetIsolate(); | 3706 Isolate* isolate = proxy->GetIsolate(); |
| 3687 | 3707 |
| 3688 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3708 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 3689 if (name->IsSymbol()) return isolate->factory()->false_value(); | 3709 if (name->IsSymbol()) return isolate->factory()->false_value(); |
| 3690 | 3710 |
| 3691 Handle<Object> args[] = { name }; | 3711 Handle<Object> args[] = { name }; |
| 3692 Handle<Object> result = proxy->CallTrap( | 3712 Handle<Object> result; |
| 3693 "delete", Handle<Object>(), ARRAY_SIZE(args), args); | 3713 ASSIGN_RETURN_ON_EXCEPTION( |
| 3694 if (isolate->has_pending_exception()) return Handle<Object>(); | 3714 isolate, result, |
| 3715 CallTrap(proxy, |
| 3716 "delete", |
| 3717 Handle<Object>(), |
| 3718 ARRAY_SIZE(args), |
| 3719 args), |
| 3720 Object); |
| 3695 | 3721 |
| 3696 bool result_bool = result->BooleanValue(); | 3722 bool result_bool = result->BooleanValue(); |
| 3697 if (mode == STRICT_DELETION && !result_bool) { | 3723 if (mode == STRICT_DELETION && !result_bool) { |
| 3698 Handle<Object> handler(proxy->handler(), isolate); | 3724 Handle<Object> handler(proxy->handler(), isolate); |
| 3699 Handle<String> trap_name = isolate->factory()->InternalizeOneByteString( | 3725 Handle<String> trap_name = isolate->factory()->InternalizeOneByteString( |
| 3700 STATIC_ASCII_VECTOR("delete")); | 3726 STATIC_ASCII_VECTOR("delete")); |
| 3701 Handle<Object> args[] = { handler, trap_name }; | 3727 Handle<Object> args[] = { handler, trap_name }; |
| 3702 Handle<Object> error = isolate->factory()->NewTypeError( | 3728 Handle<Object> error = isolate->factory()->NewTypeError( |
| 3703 "handler_failed", HandleVector(args, ARRAY_SIZE(args))); | 3729 "handler_failed", HandleVector(args, ARRAY_SIZE(args))); |
| 3704 isolate->Throw(*error); | 3730 return isolate->Throw<Object>(error); |
| 3705 return Handle<Object>(); | |
| 3706 } | 3731 } |
| 3707 return isolate->factory()->ToBoolean(result_bool); | 3732 return isolate->factory()->ToBoolean(result_bool); |
| 3708 } | 3733 } |
| 3709 | 3734 |
| 3710 | 3735 |
| 3711 Handle<Object> JSProxy::DeleteElementWithHandler( | 3736 MaybeHandle<Object> JSProxy::DeleteElementWithHandler( |
| 3712 Handle<JSProxy> proxy, uint32_t index, DeleteMode mode) { | 3737 Handle<JSProxy> proxy, uint32_t index, DeleteMode mode) { |
| 3713 Isolate* isolate = proxy->GetIsolate(); | 3738 Isolate* isolate = proxy->GetIsolate(); |
| 3714 Handle<String> name = isolate->factory()->Uint32ToString(index); | 3739 Handle<String> name = isolate->factory()->Uint32ToString(index); |
| 3715 return JSProxy::DeletePropertyWithHandler(proxy, name, mode); | 3740 return JSProxy::DeletePropertyWithHandler(proxy, name, mode); |
| 3716 } | 3741 } |
| 3717 | 3742 |
| 3718 | 3743 |
| 3719 PropertyAttributes JSProxy::GetPropertyAttributeWithHandler( | 3744 PropertyAttributes JSProxy::GetPropertyAttributeWithHandler( |
| 3720 Handle<JSProxy> proxy, | 3745 Handle<JSProxy> proxy, |
| 3721 Handle<JSReceiver> receiver, | 3746 Handle<JSReceiver> receiver, |
| 3722 Handle<Name> name) { | 3747 Handle<Name> name) { |
| 3723 Isolate* isolate = proxy->GetIsolate(); | 3748 Isolate* isolate = proxy->GetIsolate(); |
| 3724 HandleScope scope(isolate); | 3749 HandleScope scope(isolate); |
| 3725 | 3750 |
| 3726 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 3751 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 3727 if (name->IsSymbol()) return ABSENT; | 3752 if (name->IsSymbol()) return ABSENT; |
| 3728 | 3753 |
| 3729 Handle<Object> args[] = { name }; | 3754 Handle<Object> args[] = { name }; |
| 3730 Handle<Object> result = proxy->CallTrap( | 3755 Handle<Object> result; |
| 3731 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); | 3756 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 3732 if (isolate->has_pending_exception()) return NONE; | 3757 isolate, result, |
| 3758 proxy->CallTrap(proxy, |
| 3759 "getPropertyDescriptor", |
| 3760 Handle<Object>(), |
| 3761 ARRAY_SIZE(args), |
| 3762 args), |
| 3763 NONE); |
| 3733 | 3764 |
| 3734 if (result->IsUndefined()) return ABSENT; | 3765 if (result->IsUndefined()) return ABSENT; |
| 3735 | 3766 |
| 3736 bool has_pending_exception; | 3767 bool has_pending_exception; |
| 3737 Handle<Object> argv[] = { result }; | 3768 Handle<Object> argv[] = { result }; |
| 3738 Handle<Object> desc = Execution::Call( | 3769 Handle<Object> desc = Execution::Call( |
| 3739 isolate, isolate->to_complete_property_descriptor(), result, | 3770 isolate, isolate->to_complete_property_descriptor(), result, |
| 3740 ARRAY_SIZE(argv), argv, &has_pending_exception); | 3771 ARRAY_SIZE(argv), argv, &has_pending_exception); |
| 3741 if (has_pending_exception) return NONE; | 3772 if (has_pending_exception) return NONE; |
| 3742 | 3773 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3761 writable = isolate->factory()->ToBoolean(!setter->IsUndefined()); | 3792 writable = isolate->factory()->ToBoolean(!setter->IsUndefined()); |
| 3762 } | 3793 } |
| 3763 | 3794 |
| 3764 if (configurable->IsFalse()) { | 3795 if (configurable->IsFalse()) { |
| 3765 Handle<Object> handler(proxy->handler(), isolate); | 3796 Handle<Object> handler(proxy->handler(), isolate); |
| 3766 Handle<String> trap = isolate->factory()->InternalizeOneByteString( | 3797 Handle<String> trap = isolate->factory()->InternalizeOneByteString( |
| 3767 STATIC_ASCII_VECTOR("getPropertyDescriptor")); | 3798 STATIC_ASCII_VECTOR("getPropertyDescriptor")); |
| 3768 Handle<Object> args[] = { handler, trap, name }; | 3799 Handle<Object> args[] = { handler, trap, name }; |
| 3769 Handle<Object> error = isolate->factory()->NewTypeError( | 3800 Handle<Object> error = isolate->factory()->NewTypeError( |
| 3770 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); | 3801 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); |
| 3771 isolate->Throw(*error); | 3802 isolate->Throw<Object>(error); |
| 3772 return NONE; | 3803 return NONE; |
| 3773 } | 3804 } |
| 3774 | 3805 |
| 3775 int attributes = NONE; | 3806 int attributes = NONE; |
| 3776 if (!enumerable->BooleanValue()) attributes |= DONT_ENUM; | 3807 if (!enumerable->BooleanValue()) attributes |= DONT_ENUM; |
| 3777 if (!configurable->BooleanValue()) attributes |= DONT_DELETE; | 3808 if (!configurable->BooleanValue()) attributes |= DONT_DELETE; |
| 3778 if (!writable->BooleanValue()) attributes |= READ_ONLY; | 3809 if (!writable->BooleanValue()) attributes |= READ_ONLY; |
| 3779 return static_cast<PropertyAttributes>(attributes); | 3810 return static_cast<PropertyAttributes>(attributes); |
| 3780 } | 3811 } |
| 3781 | 3812 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 3805 ASSERT(proxy->IsJSObject()); | 3836 ASSERT(proxy->IsJSObject()); |
| 3806 | 3837 |
| 3807 // Inherit identity, if it was present. | 3838 // Inherit identity, if it was present. |
| 3808 if (hash->IsSmi()) { | 3839 if (hash->IsSmi()) { |
| 3809 JSObject::SetIdentityHash(Handle<JSObject>::cast(proxy), | 3840 JSObject::SetIdentityHash(Handle<JSObject>::cast(proxy), |
| 3810 Handle<Smi>::cast(hash)); | 3841 Handle<Smi>::cast(hash)); |
| 3811 } | 3842 } |
| 3812 } | 3843 } |
| 3813 | 3844 |
| 3814 | 3845 |
| 3815 MUST_USE_RESULT Handle<Object> JSProxy::CallTrap(const char* name, | 3846 MaybeHandle<Object> JSProxy::CallTrap(Handle<JSProxy> proxy, |
| 3816 Handle<Object> derived, | 3847 const char* name, |
| 3817 int argc, | 3848 Handle<Object> derived, |
| 3818 Handle<Object> argv[]) { | 3849 int argc, |
| 3819 Isolate* isolate = GetIsolate(); | 3850 Handle<Object> argv[]) { |
| 3820 Handle<Object> handler(this->handler(), isolate); | 3851 Isolate* isolate = proxy->GetIsolate(); |
| 3852 Handle<Object> handler(proxy->handler(), isolate); |
| 3821 | 3853 |
| 3822 Handle<String> trap_name = isolate->factory()->InternalizeUtf8String(name); | 3854 Handle<String> trap_name = isolate->factory()->InternalizeUtf8String(name); |
| 3823 Handle<Object> trap = Object::GetPropertyOrElement(handler, trap_name); | 3855 Handle<Object> trap = Object::GetPropertyOrElement(handler, trap_name); |
| 3824 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, trap, Handle<Object>()); | 3856 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, trap, MaybeHandle<Object>()); |
| 3825 | 3857 |
| 3826 if (trap->IsUndefined()) { | 3858 if (trap->IsUndefined()) { |
| 3827 if (derived.is_null()) { | 3859 if (derived.is_null()) { |
| 3828 Handle<Object> args[] = { handler, trap_name }; | 3860 Handle<Object> args[] = { handler, trap_name }; |
| 3829 Handle<Object> error = isolate->factory()->NewTypeError( | 3861 Handle<Object> error = isolate->factory()->NewTypeError( |
| 3830 "handler_trap_missing", HandleVector(args, ARRAY_SIZE(args))); | 3862 "handler_trap_missing", HandleVector(args, ARRAY_SIZE(args))); |
| 3831 isolate->Throw(*error); | 3863 return isolate->Throw<Object>(error); |
| 3832 return Handle<Object>(); | |
| 3833 } | 3864 } |
| 3834 trap = Handle<Object>(derived); | 3865 trap = Handle<Object>(derived); |
| 3835 } | 3866 } |
| 3836 | 3867 |
| 3837 bool threw; | 3868 bool threw; |
| 3838 return Execution::Call(isolate, trap, handler, argc, argv, &threw); | 3869 return Execution::Call(isolate, trap, handler, argc, argv, &threw); |
| 3839 } | 3870 } |
| 3840 | 3871 |
| 3841 | 3872 |
| 3842 // TODO(mstarzinger): Temporary wrapper until handlified. | 3873 // TODO(mstarzinger): Temporary wrapper until handlified. |
| (...skipping 1443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5286 } | 5317 } |
| 5287 | 5318 |
| 5288 if (is_observed && !HasLocalProperty(object, name)) { | 5319 if (is_observed && !HasLocalProperty(object, name)) { |
| 5289 EnqueueChangeRecord(object, "delete", name, old_value); | 5320 EnqueueChangeRecord(object, "delete", name, old_value); |
| 5290 } | 5321 } |
| 5291 | 5322 |
| 5292 return result; | 5323 return result; |
| 5293 } | 5324 } |
| 5294 | 5325 |
| 5295 | 5326 |
| 5296 Handle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object, | 5327 MaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object, |
| 5297 uint32_t index, | 5328 uint32_t index, |
| 5298 DeleteMode mode) { | 5329 DeleteMode mode) { |
| 5299 if (object->IsJSProxy()) { | 5330 if (object->IsJSProxy()) { |
| 5300 return JSProxy::DeleteElementWithHandler( | 5331 return JSProxy::DeleteElementWithHandler( |
| 5301 Handle<JSProxy>::cast(object), index, mode); | 5332 Handle<JSProxy>::cast(object), index, mode); |
| 5302 } | 5333 } |
| 5303 return JSObject::DeleteElement(Handle<JSObject>::cast(object), index, mode); | 5334 return JSObject::DeleteElement(Handle<JSObject>::cast(object), index, mode); |
| 5304 } | 5335 } |
| 5305 | 5336 |
| 5306 | 5337 |
| 5307 Handle<Object> JSReceiver::DeleteProperty(Handle<JSReceiver> object, | 5338 MaybeHandle<Object> JSReceiver::DeleteProperty(Handle<JSReceiver> object, |
| 5308 Handle<Name> name, | 5339 Handle<Name> name, |
| 5309 DeleteMode mode) { | 5340 DeleteMode mode) { |
| 5310 if (object->IsJSProxy()) { | 5341 if (object->IsJSProxy()) { |
| 5311 return JSProxy::DeletePropertyWithHandler( | 5342 return JSProxy::DeletePropertyWithHandler( |
| 5312 Handle<JSProxy>::cast(object), name, mode); | 5343 Handle<JSProxy>::cast(object), name, mode); |
| 5313 } | 5344 } |
| 5314 return JSObject::DeleteProperty(Handle<JSObject>::cast(object), name, mode); | 5345 return JSObject::DeleteProperty(Handle<JSObject>::cast(object), name, mode); |
| 5315 } | 5346 } |
| 5316 | 5347 |
| 5317 | 5348 |
| 5318 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, | 5349 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, |
| 5319 ElementsKind kind, | 5350 ElementsKind kind, |
| (...skipping 6123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11443 | 11474 |
| 11444 uint32_t index = Min(old_length, new_length); | 11475 uint32_t index = Min(old_length, new_length); |
| 11445 uint32_t add_count = new_length > old_length ? new_length - old_length : 0; | 11476 uint32_t add_count = new_length > old_length ? new_length - old_length : 0; |
| 11446 uint32_t delete_count = new_length < old_length ? old_length - new_length : 0; | 11477 uint32_t delete_count = new_length < old_length ? old_length - new_length : 0; |
| 11447 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); | 11478 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
| 11448 if (delete_count > 0) { | 11479 if (delete_count > 0) { |
| 11449 for (int i = indices.length() - 1; i >= 0; i--) { | 11480 for (int i = indices.length() - 1; i >= 0; i--) { |
| 11450 // Skip deletions where the property was an accessor, leaving holes | 11481 // Skip deletions where the property was an accessor, leaving holes |
| 11451 // in the array of old values. | 11482 // in the array of old values. |
| 11452 if (old_values[i]->IsTheHole()) continue; | 11483 if (old_values[i]->IsTheHole()) continue; |
| 11453 JSObject::SetElement(deleted, indices[i] - index, old_values[i], NONE, | 11484 JSObject::SetElement( |
| 11454 SLOPPY); | 11485 deleted, indices[i] - index, old_values[i], NONE, SLOPPY).Assert(); |
| 11455 } | 11486 } |
| 11456 | 11487 |
| 11457 SetProperty(deleted, isolate->factory()->length_string(), | 11488 SetProperty(deleted, isolate->factory()->length_string(), |
| 11458 isolate->factory()->NewNumberFromUint(delete_count), | 11489 isolate->factory()->NewNumberFromUint(delete_count), |
| 11459 NONE, SLOPPY).Assert(); | 11490 NONE, SLOPPY).Assert(); |
| 11460 } | 11491 } |
| 11461 | 11492 |
| 11462 EnqueueSpliceRecord(array, index, deleted, add_count); | 11493 EnqueueSpliceRecord(array, index, deleted, add_count); |
| 11463 | 11494 |
| 11464 return hresult; | 11495 return hresult; |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11888 return GetLocalElementAccessorPair(Handle<JSObject>::cast(proto), index); | 11919 return GetLocalElementAccessorPair(Handle<JSObject>::cast(proto), index); |
| 11889 } | 11920 } |
| 11890 | 11921 |
| 11891 // Check for lookup interceptor. | 11922 // Check for lookup interceptor. |
| 11892 if (object->HasIndexedInterceptor()) return MaybeHandle<AccessorPair>(); | 11923 if (object->HasIndexedInterceptor()) return MaybeHandle<AccessorPair>(); |
| 11893 | 11924 |
| 11894 return object->GetElementsAccessor()->GetAccessorPair(object, object, index); | 11925 return object->GetElementsAccessor()->GetAccessorPair(object, object, index); |
| 11895 } | 11926 } |
| 11896 | 11927 |
| 11897 | 11928 |
| 11898 Handle<Object> JSObject::SetElementWithInterceptor( | 11929 MaybeHandle<Object> JSObject::SetElementWithInterceptor( |
| 11899 Handle<JSObject> object, | 11930 Handle<JSObject> object, |
| 11900 uint32_t index, | 11931 uint32_t index, |
| 11901 Handle<Object> value, | 11932 Handle<Object> value, |
| 11902 PropertyAttributes attributes, | 11933 PropertyAttributes attributes, |
| 11903 StrictMode strict_mode, | 11934 StrictMode strict_mode, |
| 11904 bool check_prototype, | 11935 bool check_prototype, |
| 11905 SetPropertyMode set_mode) { | 11936 SetPropertyMode set_mode) { |
| 11906 Isolate* isolate = object->GetIsolate(); | 11937 Isolate* isolate = object->GetIsolate(); |
| 11907 | 11938 |
| 11908 // Make sure that the top context does not change when doing | 11939 // Make sure that the top context does not change when doing |
| 11909 // callbacks or interceptor calls. | 11940 // callbacks or interceptor calls. |
| 11910 AssertNoContextChange ncc(isolate); | 11941 AssertNoContextChange ncc(isolate); |
| 11911 | 11942 |
| 11912 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); | 11943 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); |
| 11913 if (!interceptor->setter()->IsUndefined()) { | 11944 if (!interceptor->setter()->IsUndefined()) { |
| 11914 v8::IndexedPropertySetterCallback setter = | 11945 v8::IndexedPropertySetterCallback setter = |
| 11915 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); | 11946 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); |
| 11916 LOG(isolate, | 11947 LOG(isolate, |
| 11917 ApiIndexedPropertyAccess("interceptor-indexed-set", *object, index)); | 11948 ApiIndexedPropertyAccess("interceptor-indexed-set", *object, index)); |
| 11918 PropertyCallbackArguments args(isolate, interceptor->data(), *object, | 11949 PropertyCallbackArguments args(isolate, interceptor->data(), *object, |
| 11919 *object); | 11950 *object); |
| 11920 v8::Handle<v8::Value> result = | 11951 v8::Handle<v8::Value> result = |
| 11921 args.Call(setter, index, v8::Utils::ToLocal(value)); | 11952 args.Call(setter, index, v8::Utils::ToLocal(value)); |
| 11922 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); | 11953 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 11923 if (!result.IsEmpty()) return value; | 11954 if (!result.IsEmpty()) return value; |
| 11924 } | 11955 } |
| 11925 | 11956 |
| 11926 return SetElementWithoutInterceptor(object, index, value, attributes, | 11957 return SetElementWithoutInterceptor(object, index, value, attributes, |
| 11927 strict_mode, | 11958 strict_mode, |
| 11928 check_prototype, | 11959 check_prototype, |
| 11929 set_mode); | 11960 set_mode); |
| 11930 } | 11961 } |
| 11931 | 11962 |
| 11932 | 11963 |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12065 return false; | 12096 return false; |
| 12066 } | 12097 } |
| 12067 FixedArray* arguments = FixedArray::cast(elements->get(1)); | 12098 FixedArray* arguments = FixedArray::cast(elements->get(1)); |
| 12068 return arguments->IsDictionary(); | 12099 return arguments->IsDictionary(); |
| 12069 } | 12100 } |
| 12070 | 12101 |
| 12071 | 12102 |
| 12072 // Adding n elements in fast case is O(n*n). | 12103 // Adding n elements in fast case is O(n*n). |
| 12073 // Note: revisit design to have dual undefined values to capture absent | 12104 // Note: revisit design to have dual undefined values to capture absent |
| 12074 // elements. | 12105 // elements. |
| 12075 Handle<Object> JSObject::SetFastElement(Handle<JSObject> object, | 12106 MaybeHandle<Object> JSObject::SetFastElement(Handle<JSObject> object, |
| 12076 uint32_t index, | 12107 uint32_t index, |
| 12077 Handle<Object> value, | 12108 Handle<Object> value, |
| 12078 StrictMode strict_mode, | 12109 StrictMode strict_mode, |
| 12079 bool check_prototype) { | 12110 bool check_prototype) { |
| 12080 ASSERT(object->HasFastSmiOrObjectElements() || | 12111 ASSERT(object->HasFastSmiOrObjectElements() || |
| 12081 object->HasFastArgumentsElements()); | 12112 object->HasFastArgumentsElements()); |
| 12082 | 12113 |
| 12083 Isolate* isolate = object->GetIsolate(); | 12114 Isolate* isolate = object->GetIsolate(); |
| 12084 | 12115 |
| 12085 // Array optimizations rely on the prototype lookups of Array objects always | 12116 // Array optimizations rely on the prototype lookups of Array objects always |
| 12086 // returning undefined. If there is a store to the initial prototype object, | 12117 // returning undefined. If there is a store to the initial prototype object, |
| 12087 // make sure all of these optimizations are invalidated. | 12118 // make sure all of these optimizations are invalidated. |
| 12088 if (isolate->is_initial_object_prototype(*object) || | 12119 if (isolate->is_initial_object_prototype(*object) || |
| 12089 isolate->is_initial_array_prototype(*object)) { | 12120 isolate->is_initial_array_prototype(*object)) { |
| 12090 object->map()->dependent_code()->DeoptimizeDependentCodeGroup(isolate, | 12121 object->map()->dependent_code()->DeoptimizeDependentCodeGroup(isolate, |
| 12091 DependentCode::kElementsCantBeAddedGroup); | 12122 DependentCode::kElementsCantBeAddedGroup); |
| 12092 } | 12123 } |
| 12093 | 12124 |
| 12094 Handle<FixedArray> backing_store(FixedArray::cast(object->elements())); | 12125 Handle<FixedArray> backing_store(FixedArray::cast(object->elements())); |
| 12095 if (backing_store->map() == | 12126 if (backing_store->map() == |
| 12096 isolate->heap()->sloppy_arguments_elements_map()) { | 12127 isolate->heap()->sloppy_arguments_elements_map()) { |
| 12097 backing_store = handle(FixedArray::cast(backing_store->get(1))); | 12128 backing_store = handle(FixedArray::cast(backing_store->get(1))); |
| 12098 } else { | 12129 } else { |
| 12099 backing_store = EnsureWritableFastElements(object); | 12130 backing_store = EnsureWritableFastElements(object); |
| 12100 } | 12131 } |
| 12101 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); | 12132 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); |
| 12102 | 12133 |
| 12103 if (check_prototype && | 12134 if (check_prototype && |
| 12104 (index >= capacity || backing_store->get(index)->IsTheHole())) { | 12135 (index >= capacity || backing_store->get(index)->IsTheHole())) { |
| 12105 bool found; | 12136 bool found; |
| 12106 Handle<Object> result = SetElementWithCallbackSetterInPrototypes( | 12137 MaybeHandle<Object> result = SetElementWithCallbackSetterInPrototypes( |
| 12107 object, index, value, &found, strict_mode); | 12138 object, index, value, &found, strict_mode); |
| 12108 if (found) return result; | 12139 if (found) return result; |
| 12109 } | 12140 } |
| 12110 | 12141 |
| 12111 uint32_t new_capacity = capacity; | 12142 uint32_t new_capacity = capacity; |
| 12112 // Check if the length property of this object needs to be updated. | 12143 // Check if the length property of this object needs to be updated. |
| 12113 uint32_t array_length = 0; | 12144 uint32_t array_length = 0; |
| 12114 bool must_update_array_length = false; | 12145 bool must_update_array_length = false; |
| 12115 bool introduces_holes = true; | 12146 bool introduces_holes = true; |
| 12116 if (object->IsJSArray()) { | 12147 if (object->IsJSArray()) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12193 // Finally, set the new element and length. | 12224 // Finally, set the new element and length. |
| 12194 ASSERT(object->elements()->IsFixedArray()); | 12225 ASSERT(object->elements()->IsFixedArray()); |
| 12195 backing_store->set(index, *value); | 12226 backing_store->set(index, *value); |
| 12196 if (must_update_array_length) { | 12227 if (must_update_array_length) { |
| 12197 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length)); | 12228 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length)); |
| 12198 } | 12229 } |
| 12199 return value; | 12230 return value; |
| 12200 } | 12231 } |
| 12201 | 12232 |
| 12202 | 12233 |
| 12203 Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object, | 12234 MaybeHandle<Object> JSObject::SetDictionaryElement( |
| 12204 uint32_t index, | 12235 Handle<JSObject> object, |
| 12205 Handle<Object> value, | 12236 uint32_t index, |
| 12206 PropertyAttributes attributes, | 12237 Handle<Object> value, |
| 12207 StrictMode strict_mode, | 12238 PropertyAttributes attributes, |
| 12208 bool check_prototype, | 12239 StrictMode strict_mode, |
| 12209 SetPropertyMode set_mode) { | 12240 bool check_prototype, |
| 12241 SetPropertyMode set_mode) { |
| 12210 ASSERT(object->HasDictionaryElements() || | 12242 ASSERT(object->HasDictionaryElements() || |
| 12211 object->HasDictionaryArgumentsElements()); | 12243 object->HasDictionaryArgumentsElements()); |
| 12212 Isolate* isolate = object->GetIsolate(); | 12244 Isolate* isolate = object->GetIsolate(); |
| 12213 | 12245 |
| 12214 // Insert element in the dictionary. | 12246 // Insert element in the dictionary. |
| 12215 Handle<FixedArray> elements(FixedArray::cast(object->elements())); | 12247 Handle<FixedArray> elements(FixedArray::cast(object->elements())); |
| 12216 bool is_arguments = | 12248 bool is_arguments = |
| 12217 (elements->map() == isolate->heap()->sloppy_arguments_elements_map()); | 12249 (elements->map() == isolate->heap()->sloppy_arguments_elements_map()); |
| 12218 Handle<SeededNumberDictionary> dictionary(is_arguments | 12250 Handle<SeededNumberDictionary> dictionary(is_arguments |
| 12219 ? SeededNumberDictionary::cast(elements->get(1)) | 12251 ? SeededNumberDictionary::cast(elements->get(1)) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 12237 dictionary->DetailsAtPut(entry, details); | 12269 dictionary->DetailsAtPut(entry, details); |
| 12238 } else if (details.IsReadOnly() && !element->IsTheHole()) { | 12270 } else if (details.IsReadOnly() && !element->IsTheHole()) { |
| 12239 if (strict_mode == SLOPPY) { | 12271 if (strict_mode == SLOPPY) { |
| 12240 return isolate->factory()->undefined_value(); | 12272 return isolate->factory()->undefined_value(); |
| 12241 } else { | 12273 } else { |
| 12242 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12274 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 12243 Handle<Object> args[2] = { number, object }; | 12275 Handle<Object> args[2] = { number, object }; |
| 12244 Handle<Object> error = | 12276 Handle<Object> error = |
| 12245 isolate->factory()->NewTypeError("strict_read_only_property", | 12277 isolate->factory()->NewTypeError("strict_read_only_property", |
| 12246 HandleVector(args, 2)); | 12278 HandleVector(args, 2)); |
| 12247 isolate->Throw(*error); | 12279 return isolate->Throw<Object>(error); |
| 12248 return Handle<Object>(); | |
| 12249 } | 12280 } |
| 12250 } | 12281 } |
| 12251 // Elements of the arguments object in slow mode might be slow aliases. | 12282 // Elements of the arguments object in slow mode might be slow aliases. |
| 12252 if (is_arguments && element->IsAliasedArgumentsEntry()) { | 12283 if (is_arguments && element->IsAliasedArgumentsEntry()) { |
| 12253 Handle<AliasedArgumentsEntry> entry = | 12284 Handle<AliasedArgumentsEntry> entry = |
| 12254 Handle<AliasedArgumentsEntry>::cast(element); | 12285 Handle<AliasedArgumentsEntry>::cast(element); |
| 12255 Handle<Context> context(Context::cast(elements->get(0))); | 12286 Handle<Context> context(Context::cast(elements->get(0))); |
| 12256 int context_index = entry->aliased_context_slot(); | 12287 int context_index = entry->aliased_context_slot(); |
| 12257 ASSERT(!context->get(context_index)->IsTheHole()); | 12288 ASSERT(!context->get(context_index)->IsTheHole()); |
| 12258 context->set(context_index, *value); | 12289 context->set(context_index, *value); |
| 12259 // For elements that are still writable we keep slow aliasing. | 12290 // For elements that are still writable we keep slow aliasing. |
| 12260 if (!details.IsReadOnly()) value = element; | 12291 if (!details.IsReadOnly()) value = element; |
| 12261 } | 12292 } |
| 12262 dictionary->ValueAtPut(entry, *value); | 12293 dictionary->ValueAtPut(entry, *value); |
| 12263 } | 12294 } |
| 12264 } else { | 12295 } else { |
| 12265 // Index not already used. Look for an accessor in the prototype chain. | 12296 // Index not already used. Look for an accessor in the prototype chain. |
| 12266 // Can cause GC! | 12297 // Can cause GC! |
| 12267 if (check_prototype) { | 12298 if (check_prototype) { |
| 12268 bool found; | 12299 bool found; |
| 12269 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object, | 12300 MaybeHandle<Object> result = SetElementWithCallbackSetterInPrototypes( |
| 12270 index, value, &found, strict_mode); | 12301 object, index, value, &found, strict_mode); |
| 12271 if (found) return result; | 12302 if (found) return result; |
| 12272 } | 12303 } |
| 12273 | 12304 |
| 12274 // When we set the is_extensible flag to false we always force the | 12305 // When we set the is_extensible flag to false we always force the |
| 12275 // element into dictionary mode (and force them to stay there). | 12306 // element into dictionary mode (and force them to stay there). |
| 12276 if (!object->map()->is_extensible()) { | 12307 if (!object->map()->is_extensible()) { |
| 12277 if (strict_mode == SLOPPY) { | 12308 if (strict_mode == SLOPPY) { |
| 12278 return isolate->factory()->undefined_value(); | 12309 return isolate->factory()->undefined_value(); |
| 12279 } else { | 12310 } else { |
| 12280 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12311 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 12281 Handle<String> name = isolate->factory()->NumberToString(number); | 12312 Handle<String> name = isolate->factory()->NumberToString(number); |
| 12282 Handle<Object> args[1] = { name }; | 12313 Handle<Object> args[1] = { name }; |
| 12283 Handle<Object> error = | 12314 Handle<Object> error = |
| 12284 isolate->factory()->NewTypeError("object_not_extensible", | 12315 isolate->factory()->NewTypeError("object_not_extensible", |
| 12285 HandleVector(args, 1)); | 12316 HandleVector(args, 1)); |
| 12286 isolate->Throw(*error); | 12317 return isolate->Throw<Object>(error); |
| 12287 return Handle<Object>(); | |
| 12288 } | 12318 } |
| 12289 } | 12319 } |
| 12290 | 12320 |
| 12291 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); | 12321 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); |
| 12292 Handle<SeededNumberDictionary> new_dictionary = | 12322 Handle<SeededNumberDictionary> new_dictionary = |
| 12293 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, | 12323 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, |
| 12294 details); | 12324 details); |
| 12295 if (*dictionary != *new_dictionary) { | 12325 if (*dictionary != *new_dictionary) { |
| 12296 if (is_arguments) { | 12326 if (is_arguments) { |
| 12297 elements->set(1, *new_dictionary); | 12327 elements->set(1, *new_dictionary); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12336 #ifdef DEBUG | 12366 #ifdef DEBUG |
| 12337 if (FLAG_trace_normalization) { | 12367 if (FLAG_trace_normalization) { |
| 12338 PrintF("Object elements are fast case again:\n"); | 12368 PrintF("Object elements are fast case again:\n"); |
| 12339 object->Print(); | 12369 object->Print(); |
| 12340 } | 12370 } |
| 12341 #endif | 12371 #endif |
| 12342 } | 12372 } |
| 12343 return value; | 12373 return value; |
| 12344 } | 12374 } |
| 12345 | 12375 |
| 12346 Handle<Object> JSObject::SetFastDoubleElement( | 12376 MaybeHandle<Object> JSObject::SetFastDoubleElement( |
| 12347 Handle<JSObject> object, | 12377 Handle<JSObject> object, |
| 12348 uint32_t index, | 12378 uint32_t index, |
| 12349 Handle<Object> value, | 12379 Handle<Object> value, |
| 12350 StrictMode strict_mode, | 12380 StrictMode strict_mode, |
| 12351 bool check_prototype) { | 12381 bool check_prototype) { |
| 12352 ASSERT(object->HasFastDoubleElements()); | 12382 ASSERT(object->HasFastDoubleElements()); |
| 12353 | 12383 |
| 12354 Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements())); | 12384 Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements())); |
| 12355 uint32_t elms_length = static_cast<uint32_t>(base_elms->length()); | 12385 uint32_t elms_length = static_cast<uint32_t>(base_elms->length()); |
| 12356 | 12386 |
| 12357 // If storing to an element that isn't in the array, pass the store request | 12387 // If storing to an element that isn't in the array, pass the store request |
| 12358 // up the prototype chain before storing in the receiver's elements. | 12388 // up the prototype chain before storing in the receiver's elements. |
| 12359 if (check_prototype && | 12389 if (check_prototype && |
| 12360 (index >= elms_length || | 12390 (index >= elms_length || |
| 12361 Handle<FixedDoubleArray>::cast(base_elms)->is_the_hole(index))) { | 12391 Handle<FixedDoubleArray>::cast(base_elms)->is_the_hole(index))) { |
| 12362 bool found; | 12392 bool found; |
| 12363 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object, | 12393 MaybeHandle<Object> result = SetElementWithCallbackSetterInPrototypes( |
| 12364 index, value, &found, strict_mode); | 12394 object, index, value, &found, strict_mode); |
| 12365 if (found) return result; | 12395 if (found) return result; |
| 12366 } | 12396 } |
| 12367 | 12397 |
| 12368 // If the value object is not a heap number, switch to fast elements and try | 12398 // If the value object is not a heap number, switch to fast elements and try |
| 12369 // again. | 12399 // again. |
| 12370 bool value_is_smi = value->IsSmi(); | 12400 bool value_is_smi = value->IsSmi(); |
| 12371 bool introduces_holes = true; | 12401 bool introduces_holes = true; |
| 12372 uint32_t length = elms_length; | 12402 uint32_t length = elms_length; |
| 12373 if (object->IsJSArray()) { | 12403 if (object->IsJSArray()) { |
| 12374 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&length)); | 12404 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&length)); |
| 12375 introduces_holes = index > length; | 12405 introduces_holes = index > length; |
| 12376 } else { | 12406 } else { |
| 12377 introduces_holes = index >= elms_length; | 12407 introduces_holes = index >= elms_length; |
| 12378 } | 12408 } |
| 12379 | 12409 |
| 12380 if (!value->IsNumber()) { | 12410 if (!value->IsNumber()) { |
| 12381 SetFastElementsCapacityAndLength(object, elms_length, length, | 12411 SetFastElementsCapacityAndLength(object, elms_length, length, |
| 12382 kDontAllowSmiElements); | 12412 kDontAllowSmiElements); |
| 12383 Handle<Object> result = SetFastElement(object, index, value, strict_mode, | 12413 Handle<Object> result; |
| 12384 check_prototype); | 12414 ASSIGN_RETURN_ON_EXCEPTION( |
| 12385 RETURN_IF_EMPTY_HANDLE_VALUE(object->GetIsolate(), result, | 12415 object->GetIsolate(), result, |
| 12386 Handle<Object>()); | 12416 SetFastElement(object, index, value, strict_mode, check_prototype), |
| 12417 Object); |
| 12387 object->ValidateElements(); | 12418 object->ValidateElements(); |
| 12388 return result; | 12419 return result; |
| 12389 } | 12420 } |
| 12390 | 12421 |
| 12391 double double_value = value_is_smi | 12422 double double_value = value_is_smi |
| 12392 ? static_cast<double>(Handle<Smi>::cast(value)->value()) | 12423 ? static_cast<double>(Handle<Smi>::cast(value)->value()) |
| 12393 : Handle<HeapNumber>::cast(value)->value(); | 12424 : Handle<HeapNumber>::cast(value)->value(); |
| 12394 | 12425 |
| 12395 // If the array is growing, and it's not growth by a single element at the | 12426 // If the array is growing, and it's not growth by a single element at the |
| 12396 // end, make sure that the ElementsKind is HOLEY. | 12427 // end, make sure that the ElementsKind is HOLEY. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12434 ASSERT(object->map()->has_fast_double_elements()); | 12465 ASSERT(object->map()->has_fast_double_elements()); |
| 12435 ASSERT(object->elements()->IsFixedDoubleArray() || | 12466 ASSERT(object->elements()->IsFixedDoubleArray() || |
| 12436 object->elements()->length() == 0); | 12467 object->elements()->length() == 0); |
| 12437 | 12468 |
| 12438 NormalizeElements(object); | 12469 NormalizeElements(object); |
| 12439 ASSERT(object->HasDictionaryElements()); | 12470 ASSERT(object->HasDictionaryElements()); |
| 12440 return SetElement(object, index, value, NONE, strict_mode, check_prototype); | 12471 return SetElement(object, index, value, NONE, strict_mode, check_prototype); |
| 12441 } | 12472 } |
| 12442 | 12473 |
| 12443 | 12474 |
| 12444 Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, | 12475 MaybeHandle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, |
| 12445 uint32_t index, | 12476 uint32_t index, |
| 12446 Handle<Object> value, | 12477 Handle<Object> value, |
| 12447 PropertyAttributes attributes, | 12478 PropertyAttributes attributes, |
| 12448 StrictMode strict_mode) { | 12479 StrictMode strict_mode) { |
| 12449 if (object->IsJSProxy()) { | 12480 if (object->IsJSProxy()) { |
| 12450 return JSProxy::SetElementWithHandler( | 12481 return JSProxy::SetElementWithHandler( |
| 12451 Handle<JSProxy>::cast(object), object, index, value, strict_mode); | 12482 Handle<JSProxy>::cast(object), object, index, value, strict_mode); |
| 12452 } | 12483 } |
| 12453 return JSObject::SetElement( | 12484 return JSObject::SetElement( |
| 12454 Handle<JSObject>::cast(object), index, value, attributes, strict_mode); | 12485 Handle<JSObject>::cast(object), index, value, attributes, strict_mode); |
| 12455 } | 12486 } |
| 12456 | 12487 |
| 12457 | 12488 |
| 12458 Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object, | 12489 MaybeHandle<Object> JSObject::SetOwnElement(Handle<JSObject> object, |
| 12459 uint32_t index, | 12490 uint32_t index, |
| 12460 Handle<Object> value, | 12491 Handle<Object> value, |
| 12461 StrictMode strict_mode) { | 12492 StrictMode strict_mode) { |
| 12462 ASSERT(!object->HasExternalArrayElements()); | 12493 ASSERT(!object->HasExternalArrayElements()); |
| 12463 return JSObject::SetElement(object, index, value, NONE, strict_mode, false); | 12494 return JSObject::SetElement(object, index, value, NONE, strict_mode, false); |
| 12464 } | 12495 } |
| 12465 | 12496 |
| 12466 | 12497 |
| 12467 Handle<Object> JSObject::SetElement(Handle<JSObject> object, | 12498 MaybeHandle<Object> JSObject::SetElement(Handle<JSObject> object, |
| 12468 uint32_t index, | 12499 uint32_t index, |
| 12469 Handle<Object> value, | 12500 Handle<Object> value, |
| 12470 PropertyAttributes attributes, | 12501 PropertyAttributes attributes, |
| 12471 StrictMode strict_mode, | 12502 StrictMode strict_mode, |
| 12472 bool check_prototype, | 12503 bool check_prototype, |
| 12473 SetPropertyMode set_mode) { | 12504 SetPropertyMode set_mode) { |
| 12474 Isolate* isolate = object->GetIsolate(); | 12505 Isolate* isolate = object->GetIsolate(); |
| 12475 | 12506 |
| 12476 if (object->HasExternalArrayElements() || | 12507 if (object->HasExternalArrayElements() || |
| 12477 object->HasFixedTypedArrayElements()) { | 12508 object->HasFixedTypedArrayElements()) { |
| 12478 if (!value->IsNumber() && !value->IsUndefined()) { | 12509 if (!value->IsNumber() && !value->IsUndefined()) { |
| 12479 bool has_exception; | 12510 bool has_exception; |
| 12480 Handle<Object> number = | 12511 Handle<Object> number = |
| 12481 Execution::ToNumber(isolate, value, &has_exception); | 12512 Execution::ToNumber(isolate, value, &has_exception); |
| 12482 if (has_exception) return Handle<Object>(); | 12513 if (has_exception) return MaybeHandle<Object>(); |
| 12483 value = number; | 12514 value = number; |
| 12484 } | 12515 } |
| 12485 } | 12516 } |
| 12486 | 12517 |
| 12487 // Check access rights if needed. | 12518 // Check access rights if needed. |
| 12488 if (object->IsAccessCheckNeeded()) { | 12519 if (object->IsAccessCheckNeeded()) { |
| 12489 if (!isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_SET)) { | 12520 if (!isolate->MayIndexedAccessWrapper(object, index, v8::ACCESS_SET)) { |
| 12490 isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET); | 12521 isolate->ReportFailedAccessCheckWrapper(object, v8::ACCESS_SET); |
| 12491 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); | 12522 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 12492 return value; | 12523 return value; |
| 12493 } | 12524 } |
| 12494 } | 12525 } |
| 12495 | 12526 |
| 12496 if (object->IsJSGlobalProxy()) { | 12527 if (object->IsJSGlobalProxy()) { |
| 12497 Handle<Object> proto(object->GetPrototype(), isolate); | 12528 Handle<Object> proto(object->GetPrototype(), isolate); |
| 12498 if (proto->IsNull()) return value; | 12529 if (proto->IsNull()) return value; |
| 12499 ASSERT(proto->IsJSGlobalObject()); | 12530 ASSERT(proto->IsJSGlobalObject()); |
| 12500 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, | 12531 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, |
| 12501 strict_mode, | 12532 strict_mode, |
| 12502 check_prototype, | 12533 check_prototype, |
| 12503 set_mode); | 12534 set_mode); |
| 12504 } | 12535 } |
| 12505 | 12536 |
| 12506 // Don't allow element properties to be redefined for external arrays. | 12537 // Don't allow element properties to be redefined for external arrays. |
| 12507 if ((object->HasExternalArrayElements() || | 12538 if ((object->HasExternalArrayElements() || |
| 12508 object->HasFixedTypedArrayElements()) && | 12539 object->HasFixedTypedArrayElements()) && |
| 12509 set_mode == DEFINE_PROPERTY) { | 12540 set_mode == DEFINE_PROPERTY) { |
| 12510 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12541 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 12511 Handle<Object> args[] = { object, number }; | 12542 Handle<Object> args[] = { object, number }; |
| 12512 Handle<Object> error = isolate->factory()->NewTypeError( | 12543 Handle<Object> error = isolate->factory()->NewTypeError( |
| 12513 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); | 12544 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); |
| 12514 isolate->Throw(*error); | 12545 return isolate->Throw<Object>(error); |
| 12515 return Handle<Object>(); | |
| 12516 } | 12546 } |
| 12517 | 12547 |
| 12518 // Normalize the elements to enable attributes on the property. | 12548 // Normalize the elements to enable attributes on the property. |
| 12519 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { | 12549 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { |
| 12520 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 12550 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
| 12521 // Make sure that we never go back to fast case. | 12551 // Make sure that we never go back to fast case. |
| 12522 dictionary->set_requires_slow_elements(); | 12552 dictionary->set_requires_slow_elements(); |
| 12523 } | 12553 } |
| 12524 | 12554 |
| 12525 if (!object->map()->is_observed()) { | 12555 if (!object->map()->is_observed()) { |
| 12526 return object->HasIndexedInterceptor() | 12556 return object->HasIndexedInterceptor() |
| 12527 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode, | 12557 ? SetElementWithInterceptor(object, index, value, attributes, |
| 12528 check_prototype, | 12558 strict_mode, check_prototype, set_mode) |
| 12529 set_mode) | |
| 12530 : SetElementWithoutInterceptor(object, index, value, attributes, | 12559 : SetElementWithoutInterceptor(object, index, value, attributes, |
| 12531 strict_mode, | 12560 strict_mode, check_prototype, set_mode); |
| 12532 check_prototype, | |
| 12533 set_mode); | |
| 12534 } | 12561 } |
| 12535 | 12562 |
| 12536 PropertyAttributes old_attributes = | 12563 PropertyAttributes old_attributes = |
| 12537 JSReceiver::GetLocalElementAttribute(object, index); | 12564 JSReceiver::GetLocalElementAttribute(object, index); |
| 12538 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 12565 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
| 12539 Handle<Object> old_length_handle; | 12566 Handle<Object> old_length_handle; |
| 12540 Handle<Object> new_length_handle; | 12567 Handle<Object> new_length_handle; |
| 12541 | 12568 |
| 12542 if (old_attributes != ABSENT) { | 12569 if (old_attributes != ABSENT) { |
| 12543 if (GetLocalElementAccessorPair(object, index).is_null()) { | 12570 if (GetLocalElementAccessorPair(object, index).is_null()) { |
| 12544 old_value = Object::GetElementNoExceptionThrown(isolate, object, index); | 12571 old_value = Object::GetElementNoExceptionThrown(isolate, object, index); |
| 12545 } | 12572 } |
| 12546 } else if (object->IsJSArray()) { | 12573 } else if (object->IsJSArray()) { |
| 12547 // Store old array length in case adding an element grows the array. | 12574 // Store old array length in case adding an element grows the array. |
| 12548 old_length_handle = handle(Handle<JSArray>::cast(object)->length(), | 12575 old_length_handle = handle(Handle<JSArray>::cast(object)->length(), |
| 12549 isolate); | 12576 isolate); |
| 12550 } | 12577 } |
| 12551 | 12578 |
| 12552 // Check for lookup interceptor | 12579 // Check for lookup interceptor |
| 12553 Handle<Object> result = object->HasIndexedInterceptor() | 12580 Handle<Object> result; |
| 12554 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode, | 12581 ASSIGN_RETURN_ON_EXCEPTION( |
| 12555 check_prototype, | 12582 isolate, result, |
| 12556 set_mode) | 12583 object->HasIndexedInterceptor() |
| 12557 : SetElementWithoutInterceptor(object, index, value, attributes, | 12584 ? SetElementWithInterceptor( |
| 12558 strict_mode, | 12585 object, index, value, attributes, |
| 12559 check_prototype, | 12586 strict_mode, check_prototype, set_mode) |
| 12560 set_mode); | 12587 : SetElementWithoutInterceptor( |
| 12561 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>()); | 12588 object, index, value, attributes, |
| 12589 strict_mode, check_prototype, set_mode), |
| 12590 Object); |
| 12562 | 12591 |
| 12563 Handle<String> name = isolate->factory()->Uint32ToString(index); | 12592 Handle<String> name = isolate->factory()->Uint32ToString(index); |
| 12564 PropertyAttributes new_attributes = GetLocalElementAttribute(object, index); | 12593 PropertyAttributes new_attributes = GetLocalElementAttribute(object, index); |
| 12565 if (old_attributes == ABSENT) { | 12594 if (old_attributes == ABSENT) { |
| 12566 if (object->IsJSArray() && | 12595 if (object->IsJSArray() && |
| 12567 !old_length_handle->SameValue( | 12596 !old_length_handle->SameValue( |
| 12568 Handle<JSArray>::cast(object)->length())) { | 12597 Handle<JSArray>::cast(object)->length())) { |
| 12569 new_length_handle = handle(Handle<JSArray>::cast(object)->length(), | 12598 new_length_handle = handle(Handle<JSArray>::cast(object)->length(), |
| 12570 isolate); | 12599 isolate); |
| 12571 uint32_t old_length = 0; | 12600 uint32_t old_length = 0; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 12595 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 12624 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
| 12596 } else if (value_changed) { | 12625 } else if (value_changed) { |
| 12597 EnqueueChangeRecord(object, "update", name, old_value); | 12626 EnqueueChangeRecord(object, "update", name, old_value); |
| 12598 } | 12627 } |
| 12599 } | 12628 } |
| 12600 | 12629 |
| 12601 return result; | 12630 return result; |
| 12602 } | 12631 } |
| 12603 | 12632 |
| 12604 | 12633 |
| 12605 Handle<Object> JSObject::SetElementWithoutInterceptor( | 12634 MaybeHandle<Object> JSObject::SetElementWithoutInterceptor( |
| 12606 Handle<JSObject> object, | 12635 Handle<JSObject> object, |
| 12607 uint32_t index, | 12636 uint32_t index, |
| 12608 Handle<Object> value, | 12637 Handle<Object> value, |
| 12609 PropertyAttributes attributes, | 12638 PropertyAttributes attributes, |
| 12610 StrictMode strict_mode, | 12639 StrictMode strict_mode, |
| 12611 bool check_prototype, | 12640 bool check_prototype, |
| 12612 SetPropertyMode set_mode) { | 12641 SetPropertyMode set_mode) { |
| 12613 ASSERT(object->HasDictionaryElements() || | 12642 ASSERT(object->HasDictionaryElements() || |
| 12614 object->HasDictionaryArgumentsElements() || | 12643 object->HasDictionaryArgumentsElements() || |
| 12615 (attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); | 12644 (attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); |
| (...skipping 4066 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16682 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16711 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16683 static const char* error_messages_[] = { | 16712 static const char* error_messages_[] = { |
| 16684 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16713 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16685 }; | 16714 }; |
| 16686 #undef ERROR_MESSAGES_TEXTS | 16715 #undef ERROR_MESSAGES_TEXTS |
| 16687 return error_messages_[reason]; | 16716 return error_messages_[reason]; |
| 16688 } | 16717 } |
| 16689 | 16718 |
| 16690 | 16719 |
| 16691 } } // namespace v8::internal | 16720 } } // namespace v8::internal |
| OLD | NEW |