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

Side by Side Diff: src/objects.cc

Issue 227573002: Return MaybeHandle from SetElement and DeleteElement. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/runtime.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 // 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
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
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
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
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
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
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
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
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
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
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
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
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 JSObject::ValidateElements(object); 12418 JSObject::ValidateElements(object);
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698