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

Side by Side Diff: src/objects.cc

Issue 24096017: Handlify JSObject::SetNormalizedProperty methods. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments by Yang Guo. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('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 622 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 ASSERT(!HasFastProperties()); 633 ASSERT(!HasFastProperties());
634 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); 634 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
635 if (IsGlobalObject()) { 635 if (IsGlobalObject()) {
636 value = PropertyCell::cast(value)->value(); 636 value = PropertyCell::cast(value)->value();
637 } 637 }
638 ASSERT(!value->IsPropertyCell() && !value->IsCell()); 638 ASSERT(!value->IsPropertyCell() && !value->IsCell());
639 return value; 639 return value;
640 } 640 }
641 641
642 642
643 Handle<Object> JSObject::SetNormalizedProperty(Handle<JSObject> object, 643 void JSObject::SetNormalizedProperty(Handle<JSObject> object,
644 LookupResult* result, 644 LookupResult* result,
645 Handle<Object> value) { 645 Handle<Object> value) {
646 CALL_HEAP_FUNCTION(object->GetIsolate(), 646 ASSERT(!object->HasFastProperties());
647 object->SetNormalizedProperty(result, *value), 647 NameDictionary* property_dictionary = object->property_dictionary();
648 Object); 648 if (object->IsGlobalObject()) {
649 Handle<PropertyCell> cell(PropertyCell::cast(
650 property_dictionary->ValueAt(result->GetDictionaryEntry())));
651 PropertyCell::SetValueInferType(cell, value);
652 } else {
653 property_dictionary->ValueAtPut(result->GetDictionaryEntry(), *value);
654 }
649 } 655 }
650 656
651 657
652 MaybeObject* JSObject::SetNormalizedProperty(LookupResult* result, 658 // TODO(mstarzinger): Temporary wrapper until handlified.
653 Object* value) { 659 static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict,
654 ASSERT(!HasFastProperties()); 660 Handle<Name> name,
655 if (IsGlobalObject()) { 661 Handle<Object> value,
656 PropertyCell* cell = PropertyCell::cast( 662 PropertyDetails details) {
657 property_dictionary()->ValueAt(result->GetDictionaryEntry())); 663 CALL_HEAP_FUNCTION(dict->GetIsolate(),
658 MaybeObject* maybe_type = cell->SetValueInferType(value); 664 dict->Add(*name, *value, details),
659 if (maybe_type->IsFailure()) return maybe_type; 665 NameDictionary);
660 } else {
661 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value);
662 }
663 return value;
664 } 666 }
665 667
666 668
667 Handle<Object> JSObject::SetNormalizedProperty(Handle<JSObject> object, 669 void JSObject::SetNormalizedProperty(Handle<JSObject> object,
668 Handle<Name> key, 670 Handle<Name> name,
669 Handle<Object> value, 671 Handle<Object> value,
670 PropertyDetails details) { 672 PropertyDetails details) {
671 CALL_HEAP_FUNCTION(object->GetIsolate(), 673 ASSERT(!object->HasFastProperties());
672 object->SetNormalizedProperty(*key, *value, details), 674 Handle<NameDictionary> property_dictionary(object->property_dictionary());
673 Object); 675 int entry = property_dictionary->FindEntry(*name);
674 }
675
676
677 MaybeObject* JSObject::SetNormalizedProperty(Name* name,
678 Object* value,
679 PropertyDetails details) {
680 ASSERT(!HasFastProperties());
681 int entry = property_dictionary()->FindEntry(name);
682 if (entry == NameDictionary::kNotFound) { 676 if (entry == NameDictionary::kNotFound) {
683 Object* store_value = value; 677 Handle<Object> store_value = value;
684 if (IsGlobalObject()) { 678 if (object->IsGlobalObject()) {
685 Heap* heap = name->GetHeap(); 679 store_value = object->GetIsolate()->factory()->NewPropertyCell(value);
686 MaybeObject* maybe_store_value = heap->AllocatePropertyCell(value);
687 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value;
688 } 680 }
689 Object* dict; 681 property_dictionary =
690 { MaybeObject* maybe_dict = 682 NameDictionaryAdd(property_dictionary, name, store_value, details);
691 property_dictionary()->Add(name, store_value, details); 683 object->set_properties(*property_dictionary);
692 if (!maybe_dict->ToObject(&dict)) return maybe_dict; 684 return;
693 }
694 set_properties(NameDictionary::cast(dict));
695 return value;
696 } 685 }
697 686
698 PropertyDetails original_details = property_dictionary()->DetailsAt(entry); 687 PropertyDetails original_details = property_dictionary->DetailsAt(entry);
699 int enumeration_index; 688 int enumeration_index;
700 // Preserve the enumeration index unless the property was deleted. 689 // Preserve the enumeration index unless the property was deleted.
701 if (original_details.IsDeleted()) { 690 if (original_details.IsDeleted()) {
702 enumeration_index = property_dictionary()->NextEnumerationIndex(); 691 enumeration_index = property_dictionary->NextEnumerationIndex();
703 property_dictionary()->SetNextEnumerationIndex(enumeration_index + 1); 692 property_dictionary->SetNextEnumerationIndex(enumeration_index + 1);
704 } else { 693 } else {
705 enumeration_index = original_details.dictionary_index(); 694 enumeration_index = original_details.dictionary_index();
706 ASSERT(enumeration_index > 0); 695 ASSERT(enumeration_index > 0);
707 } 696 }
708 697
709 details = PropertyDetails( 698 details = PropertyDetails(
710 details.attributes(), details.type(), enumeration_index); 699 details.attributes(), details.type(), enumeration_index);
711 700
712 if (IsGlobalObject()) { 701 if (object->IsGlobalObject()) {
713 PropertyCell* cell = 702 Handle<PropertyCell> cell(
714 PropertyCell::cast(property_dictionary()->ValueAt(entry)); 703 PropertyCell::cast(property_dictionary->ValueAt(entry)));
715 MaybeObject* maybe_type = cell->SetValueInferType(value); 704 PropertyCell::SetValueInferType(cell, value);
716 if (maybe_type->IsFailure()) return maybe_type;
717 // Please note we have to update the property details. 705 // Please note we have to update the property details.
718 property_dictionary()->DetailsAtPut(entry, details); 706 property_dictionary->DetailsAtPut(entry, details);
719 } else { 707 } else {
720 property_dictionary()->SetEntry(entry, name, value, details); 708 property_dictionary->SetEntry(entry, *name, *value, details);
721 } 709 }
722 return value;
723 } 710 }
724 711
725 712
726 // TODO(mstarzinger): Temporary wrapper until target is handlified. 713 // TODO(mstarzinger): Temporary wrapper until target is handlified.
727 Handle<NameDictionary> NameDictionaryShrink(Handle<NameDictionary> dict, 714 Handle<NameDictionary> NameDictionaryShrink(Handle<NameDictionary> dict,
728 Handle<Name> name) { 715 Handle<Name> name) {
729 CALL_HEAP_FUNCTION(dict->GetIsolate(), dict->Shrink(*name), NameDictionary); 716 CALL_HEAP_FUNCTION(dict->GetIsolate(), dict->Shrink(*name), NameDictionary);
730 } 717 }
731 718
732 719
733 static void CellSetValueInferType(Handle<PropertyCell> cell,
734 Handle<Object> value) {
735 CALL_HEAP_FUNCTION_VOID(cell->GetIsolate(), cell->SetValueInferType(*value));
736 }
737
738
739 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, 720 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object,
740 Handle<Name> name, 721 Handle<Name> name,
741 DeleteMode mode) { 722 DeleteMode mode) {
742 ASSERT(!object->HasFastProperties()); 723 ASSERT(!object->HasFastProperties());
743 Isolate* isolate = object->GetIsolate(); 724 Isolate* isolate = object->GetIsolate();
744 Handle<NameDictionary> dictionary(object->property_dictionary()); 725 Handle<NameDictionary> dictionary(object->property_dictionary());
745 int entry = dictionary->FindEntry(*name); 726 int entry = dictionary->FindEntry(*name);
746 if (entry != NameDictionary::kNotFound) { 727 if (entry != NameDictionary::kNotFound) {
747 // If we have a global object set the cell to the hole. 728 // If we have a global object set the cell to the hole.
748 if (object->IsGlobalObject()) { 729 if (object->IsGlobalObject()) {
749 PropertyDetails details = dictionary->DetailsAt(entry); 730 PropertyDetails details = dictionary->DetailsAt(entry);
750 if (details.IsDontDelete()) { 731 if (details.IsDontDelete()) {
751 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); 732 if (mode != FORCE_DELETION) return isolate->factory()->false_value();
752 // When forced to delete global properties, we have to make a 733 // When forced to delete global properties, we have to make a
753 // map change to invalidate any ICs that think they can load 734 // map change to invalidate any ICs that think they can load
754 // from the DontDelete cell without checking if it contains 735 // from the DontDelete cell without checking if it contains
755 // the hole value. 736 // the hole value.
756 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); 737 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
757 ASSERT(new_map->is_dictionary_map()); 738 ASSERT(new_map->is_dictionary_map());
758 object->set_map(*new_map); 739 object->set_map(*new_map);
759 } 740 }
760 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); 741 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
761 CellSetValueInferType(cell, isolate->factory()->the_hole_value()); 742 Handle<Object> value = isolate->factory()->the_hole_value();
743 PropertyCell::SetValueInferType(cell, value);
762 dictionary->DetailsAtPut(entry, details.AsDeleted()); 744 dictionary->DetailsAtPut(entry, details.AsDeleted());
763 } else { 745 } else {
764 Handle<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate); 746 Handle<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate);
765 if (*deleted == isolate->heap()->true_value()) { 747 if (*deleted == isolate->heap()->true_value()) {
766 Handle<NameDictionary> new_properties = 748 Handle<NameDictionary> new_properties =
767 NameDictionaryShrink(dictionary, name); 749 NameDictionaryShrink(dictionary, name);
768 object->set_properties(*new_properties); 750 object->set_properties(*new_properties);
769 } 751 }
770 return deleted; 752 return deleted;
771 } 753 }
(...skipping 1244 matching lines...) Expand 10 before | Expand all | Expand 10 after
2016 : initial_flag; 1998 : initial_flag;
2017 1999
2018 // Allocate new instance descriptors with (name, constant) added. 2000 // Allocate new instance descriptors with (name, constant) added.
2019 Handle<Map> new_map = CopyAddConstantDescriptor( 2001 Handle<Map> new_map = CopyAddConstantDescriptor(
2020 handle(object->map()), name, constant, attributes, flag); 2002 handle(object->map()), name, constant, attributes, flag);
2021 2003
2022 object->set_map(*new_map); 2004 object->set_map(*new_map);
2023 } 2005 }
2024 2006
2025 2007
2026 // TODO(mstarzinger): Temporary wrapper until handlified.
2027 static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict,
2028 Handle<Name> name,
2029 Handle<Object> value,
2030 PropertyDetails details) {
2031 CALL_HEAP_FUNCTION(dict->GetIsolate(),
2032 dict->Add(*name, *value, details),
2033 NameDictionary);
2034 }
2035
2036
2037 void JSObject::AddSlowProperty(Handle<JSObject> object, 2008 void JSObject::AddSlowProperty(Handle<JSObject> object,
2038 Handle<Name> name, 2009 Handle<Name> name,
2039 Handle<Object> value, 2010 Handle<Object> value,
2040 PropertyAttributes attributes) { 2011 PropertyAttributes attributes) {
2041 ASSERT(!object->HasFastProperties()); 2012 ASSERT(!object->HasFastProperties());
2042 Isolate* isolate = object->GetIsolate(); 2013 Isolate* isolate = object->GetIsolate();
2043 Handle<NameDictionary> dict(object->property_dictionary()); 2014 Handle<NameDictionary> dict(object->property_dictionary());
2044 if (object->IsGlobalObject()) { 2015 if (object->IsGlobalObject()) {
2045 // In case name is an orphaned property reuse the cell. 2016 // In case name is an orphaned property reuse the cell.
2046 int entry = dict->FindEntry(*name); 2017 int entry = dict->FindEntry(*name);
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
2179 } 2150 }
2180 bool done = false; 2151 bool done = false;
2181 Handle<Object> result_object = SetPropertyViaPrototypes( 2152 Handle<Object> result_object = SetPropertyViaPrototypes(
2182 object, name, value, attributes, strict_mode, &done); 2153 object, name, value, attributes, strict_mode, &done);
2183 if (done) return result_object; 2154 if (done) return result_object;
2184 // Add a new real property. 2155 // Add a new real property.
2185 return AddProperty(object, name, value, attributes, strict_mode); 2156 return AddProperty(object, name, value, attributes, strict_mode);
2186 } 2157 }
2187 2158
2188 2159
2189 static Handle<Object> ReplaceSlowProperty(Handle<JSObject> object, 2160 static void ReplaceSlowProperty(Handle<JSObject> object,
2190 Handle<Name> name, 2161 Handle<Name> name,
2191 Handle<Object> value, 2162 Handle<Object> value,
2192 PropertyAttributes attributes) { 2163 PropertyAttributes attributes) {
2193 NameDictionary* dictionary = object->property_dictionary(); 2164 NameDictionary* dictionary = object->property_dictionary();
2194 int old_index = dictionary->FindEntry(*name); 2165 int old_index = dictionary->FindEntry(*name);
2195 int new_enumeration_index = 0; // 0 means "Use the next available index." 2166 int new_enumeration_index = 0; // 0 means "Use the next available index."
2196 if (old_index != -1) { 2167 if (old_index != -1) {
2197 // All calls to ReplaceSlowProperty have had all transitions removed. 2168 // All calls to ReplaceSlowProperty have had all transitions removed.
2198 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index(); 2169 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index();
2199 } 2170 }
2200 2171
2201 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); 2172 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index);
2202 return JSObject::SetNormalizedProperty(object, name, value, new_details); 2173 JSObject::SetNormalizedProperty(object, name, value, new_details);
2203 } 2174 }
2204 2175
2205 2176
2206 const char* Representation::Mnemonic() const { 2177 const char* Representation::Mnemonic() const {
2207 switch (kind_) { 2178 switch (kind_) {
2208 case kNone: return "v"; 2179 case kNone: return "v";
2209 case kTagged: return "t"; 2180 case kTagged: return "t";
2210 case kSmi: return "s"; 2181 case kSmi: return "s";
2211 case kDouble: return "d"; 2182 case kDouble: return "d";
2212 case kInteger32: return "i"; 2183 case kInteger32: return "i";
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after
2782 LookupResult result(object->GetIsolate()); 2753 LookupResult result(object->GetIsolate());
2783 object->LocalLookup(*name, &result, true); 2754 object->LocalLookup(*name, &result, true);
2784 if (!result.IsFound()) { 2755 if (!result.IsFound()) {
2785 object->map()->LookupTransition(JSObject::cast(*object), *name, &result); 2756 object->map()->LookupTransition(JSObject::cast(*object), *name, &result);
2786 } 2757 }
2787 return SetProperty(object, &result, name, value, attributes, strict_mode, 2758 return SetProperty(object, &result, name, value, attributes, strict_mode,
2788 store_mode); 2759 store_mode);
2789 } 2760 }
2790 2761
2791 2762
2792 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, 2763 Handle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object,
2793 Name* name, 2764 Handle<Object> structure,
2794 Object* value, 2765 Handle<Name> name,
2795 JSObject* holder, 2766 Handle<Object> value,
2796 StrictModeFlag strict_mode) { 2767 Handle<JSObject> holder,
2797 Isolate* isolate = GetIsolate(); 2768 StrictModeFlag strict_mode) {
2798 HandleScope scope(isolate); 2769 Isolate* isolate = object->GetIsolate();
2799 2770
2800 // We should never get here to initialize a const with the hole 2771 // We should never get here to initialize a const with the hole
2801 // value since a const declaration would conflict with the setter. 2772 // value since a const declaration would conflict with the setter.
2802 ASSERT(!value->IsTheHole()); 2773 ASSERT(!value->IsTheHole());
2803 Handle<Object> value_handle(value, isolate);
2804 2774
2805 // To accommodate both the old and the new api we switch on the 2775 // To accommodate both the old and the new api we switch on the
2806 // data structure used to store the callbacks. Eventually foreign 2776 // data structure used to store the callbacks. Eventually foreign
2807 // callbacks should be phased out. 2777 // callbacks should be phased out.
2808 if (structure->IsForeign()) { 2778 if (structure->IsForeign()) {
2809 AccessorDescriptor* callback = 2779 AccessorDescriptor* callback =
2810 reinterpret_cast<AccessorDescriptor*>( 2780 reinterpret_cast<AccessorDescriptor*>(
2811 Foreign::cast(structure)->foreign_address()); 2781 Handle<Foreign>::cast(structure)->foreign_address());
2812 MaybeObject* obj = (callback->setter)( 2782 CALL_AND_RETRY_OR_DIE(isolate,
2813 isolate, this, value, callback->data); 2783 (callback->setter)(
2814 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 2784 isolate, *object, *value, callback->data),
2815 if (obj->IsFailure()) return obj; 2785 break,
2816 return *value_handle; 2786 return Handle<Object>());
2787 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
2788 return value;
2817 } 2789 }
2818 2790
2819 if (structure->IsExecutableAccessorInfo()) { 2791 if (structure->IsExecutableAccessorInfo()) {
2820 // api style callbacks 2792 // api style callbacks
2821 ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(structure); 2793 ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(*structure);
2822 if (!data->IsCompatibleReceiver(this)) { 2794 if (!data->IsCompatibleReceiver(*object)) {
2823 Handle<Object> name_handle(name, isolate); 2795 Handle<Object> args[2] = { name, object };
2824 Handle<Object> receiver_handle(this, isolate);
2825 Handle<Object> args[2] = { name_handle, receiver_handle };
2826 Handle<Object> error = 2796 Handle<Object> error =
2827 isolate->factory()->NewTypeError("incompatible_method_receiver", 2797 isolate->factory()->NewTypeError("incompatible_method_receiver",
2828 HandleVector(args, 2798 HandleVector(args,
2829 ARRAY_SIZE(args))); 2799 ARRAY_SIZE(args)));
2830 return isolate->Throw(*error); 2800 isolate->Throw(*error);
2801 return Handle<Object>();
2831 } 2802 }
2832 // TODO(rossberg): Support symbols in the API. 2803 // TODO(rossberg): Support symbols in the API.
2833 if (name->IsSymbol()) return value; 2804 if (name->IsSymbol()) return value;
2834 Object* call_obj = data->setter(); 2805 Object* call_obj = data->setter();
2835 v8::AccessorSetterCallback call_fun = 2806 v8::AccessorSetterCallback call_fun =
2836 v8::ToCData<v8::AccessorSetterCallback>(call_obj); 2807 v8::ToCData<v8::AccessorSetterCallback>(call_obj);
2837 if (call_fun == NULL) return value; 2808 if (call_fun == NULL) return value;
2838 Handle<String> key(String::cast(name)); 2809 Handle<String> key = Handle<String>::cast(name);
2839 LOG(isolate, ApiNamedPropertyAccess("store", this, name)); 2810 LOG(isolate, ApiNamedPropertyAccess("store", *object, *name));
2840 PropertyCallbackArguments args( 2811 PropertyCallbackArguments args(
2841 isolate, data->data(), this, JSObject::cast(holder)); 2812 isolate, data->data(), *object, JSObject::cast(*holder));
2842 args.Call(call_fun, 2813 args.Call(call_fun,
2843 v8::Utils::ToLocal(key), 2814 v8::Utils::ToLocal(key),
2844 v8::Utils::ToLocal(value_handle)); 2815 v8::Utils::ToLocal(value));
2845 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 2816 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
2846 return *value_handle; 2817 return value;
2847 } 2818 }
2848 2819
2849 if (structure->IsAccessorPair()) { 2820 if (structure->IsAccessorPair()) {
2850 Object* setter = AccessorPair::cast(structure)->setter(); 2821 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
2851 if (setter->IsSpecFunction()) { 2822 if (setter->IsSpecFunction()) {
2852 // TODO(rossberg): nicer would be to cast to some JSCallable here... 2823 // TODO(rossberg): nicer would be to cast to some JSCallable here...
2853 return SetPropertyWithDefinedSetter(JSReceiver::cast(setter), value); 2824 CALL_HEAP_FUNCTION(isolate,
2825 object->SetPropertyWithDefinedSetter(
2826 JSReceiver::cast(*setter), *value),
2827 Object);
2854 } else { 2828 } else {
2855 if (strict_mode == kNonStrictMode) { 2829 if (strict_mode == kNonStrictMode) {
2856 return value; 2830 return value;
2857 } 2831 }
2858 Handle<Name> key(name); 2832 Handle<Object> args[2] = { name, holder };
2859 Handle<Object> holder_handle(holder, isolate); 2833 Handle<Object> error =
2860 Handle<Object> args[2] = { key, holder_handle }; 2834 isolate->factory()->NewTypeError("no_setter_in_callback",
2861 return isolate->Throw( 2835 HandleVector(args, 2));
2862 *isolate->factory()->NewTypeError("no_setter_in_callback", 2836 isolate->Throw(*error);
2863 HandleVector(args, 2))); 2837 return Handle<Object>();
2864 } 2838 }
2865 } 2839 }
2866 2840
2867 // TODO(dcarney): Handle correctly. 2841 // TODO(dcarney): Handle correctly.
2868 if (structure->IsDeclaredAccessorInfo()) { 2842 if (structure->IsDeclaredAccessorInfo()) {
2869 return value; 2843 return value;
2870 } 2844 }
2871 2845
2872 UNREACHABLE(); 2846 UNREACHABLE();
2873 return NULL; 2847 return Handle<Object>();
2874 } 2848 }
2875 2849
2876 2850
2877 MaybeObject* JSReceiver::SetPropertyWithDefinedSetter(JSReceiver* setter, 2851 MaybeObject* JSReceiver::SetPropertyWithDefinedSetter(JSReceiver* setter,
2878 Object* value) { 2852 Object* value) {
2879 Isolate* isolate = GetIsolate(); 2853 Isolate* isolate = GetIsolate();
2880 Handle<Object> value_handle(value, isolate); 2854 Handle<Object> value_handle(value, isolate);
2881 Handle<JSReceiver> fun(setter, isolate); 2855 Handle<JSReceiver> fun(setter, isolate);
2882 Handle<JSReceiver> self(this, isolate); 2856 Handle<JSReceiver> self(this, isolate);
2883 #ifdef ENABLE_DEBUGGER_SUPPORT 2857 #ifdef ENABLE_DEBUGGER_SUPPORT
(...skipping 18 matching lines...) Expand all
2902 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( 2876 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(
2903 uint32_t index, 2877 uint32_t index,
2904 Object* value, 2878 Object* value,
2905 bool* found, 2879 bool* found,
2906 StrictModeFlag strict_mode) { 2880 StrictModeFlag strict_mode) {
2907 Heap* heap = GetHeap(); 2881 Heap* heap = GetHeap();
2908 for (Object* pt = GetPrototype(); 2882 for (Object* pt = GetPrototype();
2909 pt != heap->null_value(); 2883 pt != heap->null_value();
2910 pt = pt->GetPrototype(GetIsolate())) { 2884 pt = pt->GetPrototype(GetIsolate())) {
2911 if (pt->IsJSProxy()) { 2885 if (pt->IsJSProxy()) {
2912 String* name; 2886 Isolate* isolate = GetIsolate();
2913 MaybeObject* maybe = heap->Uint32ToString(index); 2887 HandleScope scope(isolate);
2914 if (!maybe->To<String>(&name)) { 2888 Handle<JSProxy> proxy(JSProxy::cast(pt));
2915 *found = true; // Force abort 2889 Handle<JSObject> self(this, isolate);
2916 return maybe; 2890 Handle<String> name = isolate->factory()->Uint32ToString(index);
2917 } 2891 Handle<Object> value_handle(value, isolate);
2918 return JSProxy::cast(pt)->SetPropertyViaPrototypesWithHandler( 2892 Handle<Object> result = JSProxy::SetPropertyViaPrototypesWithHandler(
2919 this, name, value, NONE, strict_mode, found); 2893 proxy, self, name, value_handle, NONE, strict_mode, found);
2894 RETURN_IF_EMPTY_HANDLE(isolate, result);
2895 return *result;
2920 } 2896 }
2921 if (!JSObject::cast(pt)->HasDictionaryElements()) { 2897 if (!JSObject::cast(pt)->HasDictionaryElements()) {
2922 continue; 2898 continue;
2923 } 2899 }
2924 SeededNumberDictionary* dictionary = 2900 SeededNumberDictionary* dictionary =
2925 JSObject::cast(pt)->element_dictionary(); 2901 JSObject::cast(pt)->element_dictionary();
2926 int entry = dictionary->FindEntry(index); 2902 int entry = dictionary->FindEntry(index);
2927 if (entry != SeededNumberDictionary::kNotFound) { 2903 if (entry != SeededNumberDictionary::kNotFound) {
2928 PropertyDetails details = dictionary->DetailsAt(entry); 2904 PropertyDetails details = dictionary->DetailsAt(entry);
2929 if (details.type() == CALLBACKS) { 2905 if (details.type() == CALLBACKS) {
2930 *found = true; 2906 *found = true;
2931 return SetElementWithCallback(dictionary->ValueAt(entry), 2907 Isolate* isolate = GetIsolate();
2932 index, 2908 HandleScope scope(isolate);
2933 value, 2909 Handle<JSObject> self(this, isolate);
2934 JSObject::cast(pt), 2910 Handle<Object> structure(dictionary->ValueAt(entry), isolate);
2935 strict_mode); 2911 Handle<Object> value_handle(value, isolate);
2912 Handle<JSObject> holder(JSObject::cast(pt));
2913 Handle<Object> result = SetElementWithCallback(
2914 self, structure, index, value_handle, holder, strict_mode);
2915 RETURN_IF_EMPTY_HANDLE(isolate, result);
2916 return *result;
2936 } 2917 }
2937 } 2918 }
2938 } 2919 }
2939 *found = false; 2920 *found = false;
2940 return heap->the_hole_value(); 2921 return heap->the_hole_value();
2941 } 2922 }
2942 2923
2924
2943 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, 2925 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object,
2944 Handle<Name> name, 2926 Handle<Name> name,
2945 Handle<Object> value, 2927 Handle<Object> value,
2946 PropertyAttributes attributes, 2928 PropertyAttributes attributes,
2947 StrictModeFlag strict_mode, 2929 StrictModeFlag strict_mode,
2948 bool* done) { 2930 bool* done) {
2949 Isolate* isolate = object->GetIsolate(); 2931 Isolate* isolate = object->GetIsolate();
2950 2932
2951 *done = false; 2933 *done = false;
2952 // We could not find a local property so let's check whether there is an 2934 // We could not find a local property so let's check whether there is an
(...skipping 11 matching lines...) Expand all
2964 case INTERCEPTOR: { 2946 case INTERCEPTOR: {
2965 PropertyAttributes attr = 2947 PropertyAttributes attr =
2966 result.holder()->GetPropertyAttributeWithInterceptor( 2948 result.holder()->GetPropertyAttributeWithInterceptor(
2967 *object, *name, true); 2949 *object, *name, true);
2968 *done = !!(attr & READ_ONLY); 2950 *done = !!(attr & READ_ONLY);
2969 break; 2951 break;
2970 } 2952 }
2971 case CALLBACKS: { 2953 case CALLBACKS: {
2972 if (!FLAG_es5_readonly && result.IsReadOnly()) break; 2954 if (!FLAG_es5_readonly && result.IsReadOnly()) break;
2973 *done = true; 2955 *done = true;
2974 CALL_HEAP_FUNCTION(isolate, 2956 Handle<Object> callback_object(result.GetCallbackObject(), isolate);
2975 object->SetPropertyWithCallback( 2957 return SetPropertyWithCallback(object, callback_object, name, value,
2976 result.GetCallbackObject(), 2958 handle(result.holder()), strict_mode);
2977 *name, *value, result.holder(), strict_mode),
2978 Object);
2979 } 2959 }
2980 case HANDLER: { 2960 case HANDLER: {
2981 CALL_HEAP_FUNCTION(isolate, 2961 Handle<JSProxy> proxy(result.proxy());
2982 result.proxy()->SetPropertyViaPrototypesWithHandler( 2962 return JSProxy::SetPropertyViaPrototypesWithHandler(
2983 *object, *name, *value, attributes, strict_mode, 2963 proxy, object, name, value, attributes, strict_mode, done);
2984 done),
2985 Object);
2986 } 2964 }
2987 case TRANSITION: 2965 case TRANSITION:
2988 case NONEXISTENT: 2966 case NONEXISTENT:
2989 UNREACHABLE(); 2967 UNREACHABLE();
2990 break; 2968 break;
2991 } 2969 }
2992 } 2970 }
2993 2971
2994 // If we get here with *done true, we have encountered a read-only property. 2972 // If we get here with *done true, we have encountered a read-only property.
2995 if (!FLAG_es5_readonly) *done = false; 2973 if (!FLAG_es5_readonly) *done = false;
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
3349 } 3327 }
3350 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); 3328 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
3351 ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR)); 3329 ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR));
3352 if (result->IsFound()) return; 3330 if (result->IsFound()) return;
3353 } 3331 }
3354 result->NotFound(); 3332 result->NotFound();
3355 } 3333 }
3356 3334
3357 3335
3358 // We only need to deal with CALLBACKS and INTERCEPTORS 3336 // We only need to deal with CALLBACKS and INTERCEPTORS
3359 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck( 3337 Handle<Object> JSObject::SetPropertyWithFailedAccessCheck(
3338 Handle<JSObject> object,
3360 LookupResult* result, 3339 LookupResult* result,
3361 Name* name, 3340 Handle<Name> name,
3362 Object* value, 3341 Handle<Object> value,
3363 bool check_prototype, 3342 bool check_prototype,
3364 StrictModeFlag strict_mode) { 3343 StrictModeFlag strict_mode) {
3365 if (check_prototype && !result->IsProperty()) { 3344 if (check_prototype && !result->IsProperty()) {
3366 LookupRealNamedPropertyInPrototypes(name, result); 3345 object->LookupRealNamedPropertyInPrototypes(*name, result);
3367 } 3346 }
3368 3347
3369 if (result->IsProperty()) { 3348 if (result->IsProperty()) {
3370 if (!result->IsReadOnly()) { 3349 if (!result->IsReadOnly()) {
3371 switch (result->type()) { 3350 switch (result->type()) {
3372 case CALLBACKS: { 3351 case CALLBACKS: {
3373 Object* obj = result->GetCallbackObject(); 3352 Object* obj = result->GetCallbackObject();
3374 if (obj->IsAccessorInfo()) { 3353 if (obj->IsAccessorInfo()) {
3375 AccessorInfo* info = AccessorInfo::cast(obj); 3354 Handle<AccessorInfo> info(AccessorInfo::cast(obj));
3376 if (info->all_can_write()) { 3355 if (info->all_can_write()) {
3377 return SetPropertyWithCallback(result->GetCallbackObject(), 3356 return SetPropertyWithCallback(object,
3357 info,
3378 name, 3358 name,
3379 value, 3359 value,
3380 result->holder(), 3360 handle(result->holder()),
3381 strict_mode); 3361 strict_mode);
3382 } 3362 }
3383 } else if (obj->IsAccessorPair()) { 3363 } else if (obj->IsAccessorPair()) {
3384 AccessorPair* pair = AccessorPair::cast(obj); 3364 Handle<AccessorPair> pair(AccessorPair::cast(obj));
3385 if (pair->all_can_read()) { 3365 if (pair->all_can_read()) {
3386 return SetPropertyWithCallback(result->GetCallbackObject(), 3366 return SetPropertyWithCallback(object,
3367 pair,
3387 name, 3368 name,
3388 value, 3369 value,
3389 result->holder(), 3370 handle(result->holder()),
3390 strict_mode); 3371 strict_mode);
3391 } 3372 }
3392 } 3373 }
3393 break; 3374 break;
3394 } 3375 }
3395 case INTERCEPTOR: { 3376 case INTERCEPTOR: {
3396 // Try lookup real named properties. Note that only property can be 3377 // Try lookup real named properties. Note that only property can be
3397 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain. 3378 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain.
3398 LookupResult r(GetIsolate()); 3379 LookupResult r(object->GetIsolate());
3399 LookupRealNamedProperty(name, &r); 3380 object->LookupRealNamedProperty(*name, &r);
3400 if (r.IsProperty()) { 3381 if (r.IsProperty()) {
3401 return SetPropertyWithFailedAccessCheck(&r, 3382 return SetPropertyWithFailedAccessCheck(object,
3383 &r,
3402 name, 3384 name,
3403 value, 3385 value,
3404 check_prototype, 3386 check_prototype,
3405 strict_mode); 3387 strict_mode);
3406 } 3388 }
3407 break; 3389 break;
3408 } 3390 }
3409 default: { 3391 default: {
3410 break; 3392 break;
3411 } 3393 }
3412 } 3394 }
3413 } 3395 }
3414 } 3396 }
3415 3397
3416 Isolate* isolate = GetIsolate(); 3398 Isolate* isolate = object->GetIsolate();
3417 HandleScope scope(isolate); 3399 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET);
3418 Handle<Object> value_handle(value, isolate); 3400 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
3419 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); 3401 return value;
3420 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
3421 return *value_handle;
3422 } 3402 }
3423 3403
3424 3404
3425 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, 3405 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
3426 LookupResult* result, 3406 LookupResult* result,
3427 Handle<Name> key, 3407 Handle<Name> key,
3428 Handle<Object> value, 3408 Handle<Object> value,
3429 PropertyAttributes attributes, 3409 PropertyAttributes attributes,
3430 StrictModeFlag strict_mode, 3410 StrictModeFlag strict_mode,
3431 StoreFromKeyed store_mode) { 3411 StoreFromKeyed store_mode) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3466 if (name->IsSymbol()) return value; 3446 if (name->IsSymbol()) return value;
3467 3447
3468 Handle<Object> args[] = { receiver, name, value }; 3448 Handle<Object> args[] = { receiver, name, value };
3469 proxy->CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); 3449 proxy->CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args);
3470 if (isolate->has_pending_exception()) return Handle<Object>(); 3450 if (isolate->has_pending_exception()) return Handle<Object>();
3471 3451
3472 return value; 3452 return value;
3473 } 3453 }
3474 3454
3475 3455
3476 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyViaPrototypesWithHandler( 3456 Handle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
3477 JSReceiver* receiver_raw, 3457 Handle<JSProxy> proxy,
3478 Name* name_raw, 3458 Handle<JSReceiver> receiver,
3479 Object* value_raw, 3459 Handle<Name> name,
3460 Handle<Object> value,
3480 PropertyAttributes attributes, 3461 PropertyAttributes attributes,
3481 StrictModeFlag strict_mode, 3462 StrictModeFlag strict_mode,
3482 bool* done) { 3463 bool* done) {
3483 Isolate* isolate = GetIsolate(); 3464 Isolate* isolate = proxy->GetIsolate();
3484 Handle<JSProxy> proxy(this); 3465 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy.
3485 Handle<JSReceiver> receiver(receiver_raw);
3486 Handle<Name> name(name_raw);
3487 Handle<Object> value(value_raw, isolate);
3488 Handle<Object> handler(this->handler(), isolate); // Trap might morph proxy.
3489 3466
3490 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 3467 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3491 if (name->IsSymbol()) { 3468 if (name->IsSymbol()) {
3492 *done = false; 3469 *done = false;
3493 return isolate->heap()->the_hole_value(); 3470 return isolate->factory()->the_hole_value();
3494 } 3471 }
3495 3472
3496 *done = true; // except where redefined... 3473 *done = true; // except where redefined...
3497 Handle<Object> args[] = { name }; 3474 Handle<Object> args[] = { name };
3498 Handle<Object> result = proxy->CallTrap( 3475 Handle<Object> result = proxy->CallTrap(
3499 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); 3476 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args);
3500 if (isolate->has_pending_exception()) return Failure::Exception(); 3477 if (isolate->has_pending_exception()) return Handle<Object>();
3501 3478
3502 if (result->IsUndefined()) { 3479 if (result->IsUndefined()) {
3503 *done = false; 3480 *done = false;
3504 return isolate->heap()->the_hole_value(); 3481 return isolate->factory()->the_hole_value();
3505 } 3482 }
3506 3483
3507 // Emulate [[GetProperty]] semantics for proxies. 3484 // Emulate [[GetProperty]] semantics for proxies.
3508 bool has_pending_exception; 3485 bool has_pending_exception;
3509 Handle<Object> argv[] = { result }; 3486 Handle<Object> argv[] = { result };
3510 Handle<Object> desc = Execution::Call( 3487 Handle<Object> desc = Execution::Call(
3511 isolate, isolate->to_complete_property_descriptor(), result, 3488 isolate, isolate->to_complete_property_descriptor(), result,
3512 ARRAY_SIZE(argv), argv, &has_pending_exception); 3489 ARRAY_SIZE(argv), argv, &has_pending_exception);
3513 if (has_pending_exception) return Failure::Exception(); 3490 if (has_pending_exception) return Handle<Object>();
3514 3491
3515 // [[GetProperty]] requires to check that all properties are configurable. 3492 // [[GetProperty]] requires to check that all properties are configurable.
3516 Handle<String> configurable_name = 3493 Handle<String> configurable_name =
3517 isolate->factory()->InternalizeOneByteString( 3494 isolate->factory()->InternalizeOneByteString(
3518 STATIC_ASCII_VECTOR("configurable_")); 3495 STATIC_ASCII_VECTOR("configurable_"));
3519 Handle<Object> configurable( 3496 Handle<Object> configurable(
3520 v8::internal::GetProperty(isolate, desc, configurable_name)); 3497 v8::internal::GetProperty(isolate, desc, configurable_name));
3521 ASSERT(!isolate->has_pending_exception()); 3498 ASSERT(!isolate->has_pending_exception());
3522 ASSERT(configurable->IsTrue() || configurable->IsFalse()); 3499 ASSERT(configurable->IsTrue() || configurable->IsFalse());
3523 if (configurable->IsFalse()) { 3500 if (configurable->IsFalse()) {
3524 Handle<String> trap = 3501 Handle<String> trap =
3525 isolate->factory()->InternalizeOneByteString( 3502 isolate->factory()->InternalizeOneByteString(
3526 STATIC_ASCII_VECTOR("getPropertyDescriptor")); 3503 STATIC_ASCII_VECTOR("getPropertyDescriptor"));
3527 Handle<Object> args[] = { handler, trap, name }; 3504 Handle<Object> args[] = { handler, trap, name };
3528 Handle<Object> error = isolate->factory()->NewTypeError( 3505 Handle<Object> error = isolate->factory()->NewTypeError(
3529 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); 3506 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args)));
3530 return isolate->Throw(*error); 3507 isolate->Throw(*error);
3508 return Handle<Object>();
3531 } 3509 }
3532 ASSERT(configurable->IsTrue()); 3510 ASSERT(configurable->IsTrue());
3533 3511
3534 // Check for DataDescriptor. 3512 // Check for DataDescriptor.
3535 Handle<String> hasWritable_name = 3513 Handle<String> hasWritable_name =
3536 isolate->factory()->InternalizeOneByteString( 3514 isolate->factory()->InternalizeOneByteString(
3537 STATIC_ASCII_VECTOR("hasWritable_")); 3515 STATIC_ASCII_VECTOR("hasWritable_"));
3538 Handle<Object> hasWritable( 3516 Handle<Object> hasWritable(
3539 v8::internal::GetProperty(isolate, desc, hasWritable_name)); 3517 v8::internal::GetProperty(isolate, desc, hasWritable_name));
3540 ASSERT(!isolate->has_pending_exception()); 3518 ASSERT(!isolate->has_pending_exception());
3541 ASSERT(hasWritable->IsTrue() || hasWritable->IsFalse()); 3519 ASSERT(hasWritable->IsTrue() || hasWritable->IsFalse());
3542 if (hasWritable->IsTrue()) { 3520 if (hasWritable->IsTrue()) {
3543 Handle<String> writable_name = 3521 Handle<String> writable_name =
3544 isolate->factory()->InternalizeOneByteString( 3522 isolate->factory()->InternalizeOneByteString(
3545 STATIC_ASCII_VECTOR("writable_")); 3523 STATIC_ASCII_VECTOR("writable_"));
3546 Handle<Object> writable( 3524 Handle<Object> writable(
3547 v8::internal::GetProperty(isolate, desc, writable_name)); 3525 v8::internal::GetProperty(isolate, desc, writable_name));
3548 ASSERT(!isolate->has_pending_exception()); 3526 ASSERT(!isolate->has_pending_exception());
3549 ASSERT(writable->IsTrue() || writable->IsFalse()); 3527 ASSERT(writable->IsTrue() || writable->IsFalse());
3550 *done = writable->IsFalse(); 3528 *done = writable->IsFalse();
3551 if (!*done) return GetHeap()->the_hole_value(); 3529 if (!*done) return isolate->factory()->the_hole_value();
3552 if (strict_mode == kNonStrictMode) return *value; 3530 if (strict_mode == kNonStrictMode) return value;
3553 Handle<Object> args[] = { name, receiver }; 3531 Handle<Object> args[] = { name, receiver };
3554 Handle<Object> error = isolate->factory()->NewTypeError( 3532 Handle<Object> error = isolate->factory()->NewTypeError(
3555 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); 3533 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
3556 return isolate->Throw(*error); 3534 isolate->Throw(*error);
3535 return Handle<Object>();
3557 } 3536 }
3558 3537
3559 // We have an AccessorDescriptor. 3538 // We have an AccessorDescriptor.
3560 Handle<String> set_name = isolate->factory()->InternalizeOneByteString( 3539 Handle<String> set_name = isolate->factory()->InternalizeOneByteString(
3561 STATIC_ASCII_VECTOR("set_")); 3540 STATIC_ASCII_VECTOR("set_"));
3562 Handle<Object> setter(v8::internal::GetProperty(isolate, desc, set_name)); 3541 Handle<Object> setter(v8::internal::GetProperty(isolate, desc, set_name));
3563 ASSERT(!isolate->has_pending_exception()); 3542 ASSERT(!isolate->has_pending_exception());
3564 if (!setter->IsUndefined()) { 3543 if (!setter->IsUndefined()) {
3565 // TODO(rossberg): nicer would be to cast to some JSCallable here... 3544 // TODO(rossberg): nicer would be to cast to some JSCallable here...
3566 return receiver->SetPropertyWithDefinedSetter( 3545 CALL_HEAP_FUNCTION(isolate,
3567 JSReceiver::cast(*setter), *value); 3546 receiver->SetPropertyWithDefinedSetter(
3547 JSReceiver::cast(*setter), *value),
3548 Object);
3568 } 3549 }
3569 3550
3570 if (strict_mode == kNonStrictMode) return *value; 3551 if (strict_mode == kNonStrictMode) return value;
3571 Handle<Object> args2[] = { name, proxy }; 3552 Handle<Object> args2[] = { name, proxy };
3572 Handle<Object> error = isolate->factory()->NewTypeError( 3553 Handle<Object> error = isolate->factory()->NewTypeError(
3573 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); 3554 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2)));
3574 return isolate->Throw(*error); 3555 isolate->Throw(*error);
3556 return Handle<Object>();
3575 } 3557 }
3576 3558
3577 3559
3578 Handle<Object> JSProxy::DeletePropertyWithHandler( 3560 Handle<Object> JSProxy::DeletePropertyWithHandler(
3579 Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) { 3561 Handle<JSProxy> proxy, Handle<Name> name, DeleteMode mode) {
3580 Isolate* isolate = proxy->GetIsolate(); 3562 Isolate* isolate = proxy->GetIsolate();
3581 3563
3582 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 3564 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3583 if (name->IsSymbol()) return isolate->factory()->false_value(); 3565 if (name->IsSymbol()) return isolate->factory()->false_value();
3584 3566
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
3807 descriptors = transition_map->instance_descriptors(); 3789 descriptors = transition_map->instance_descriptors();
3808 representation = descriptors->GetDetails(descriptor).representation(); 3790 representation = descriptors->GetDetails(descriptor).representation();
3809 } 3791 }
3810 3792
3811 int field_index = descriptors->GetFieldIndex(descriptor); 3793 int field_index = descriptors->GetFieldIndex(descriptor);
3812 return AddFastPropertyUsingMap( 3794 return AddFastPropertyUsingMap(
3813 object, transition_map, name, value, field_index, representation); 3795 object, transition_map, name, value, field_index, representation);
3814 } 3796 }
3815 3797
3816 3798
3817 static Handle<Object> SetPropertyToField(LookupResult* lookup, 3799 static void SetPropertyToField(LookupResult* lookup,
3818 Handle<Name> name, 3800 Handle<Name> name,
3819 Handle<Object> value) { 3801 Handle<Object> value) {
3820 Representation representation = lookup->representation(); 3802 Representation representation = lookup->representation();
3821 if (!value->FitsRepresentation(representation) || 3803 if (!value->FitsRepresentation(representation) ||
3822 lookup->type() == CONSTANT) { 3804 lookup->type() == CONSTANT) {
3823 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), 3805 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()),
3824 lookup->GetDescriptorIndex(), 3806 lookup->GetDescriptorIndex(),
3825 value->OptimalRepresentation(), 3807 value->OptimalRepresentation(),
3826 FORCE_FIELD); 3808 FORCE_FIELD);
3827 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); 3809 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
3828 int descriptor = lookup->GetDescriptorIndex(); 3810 int descriptor = lookup->GetDescriptorIndex();
3829 representation = desc->GetDetails(descriptor).representation(); 3811 representation = desc->GetDetails(descriptor).representation();
3830 } 3812 }
3831 3813
3832 if (FLAG_track_double_fields && representation.IsDouble()) { 3814 if (FLAG_track_double_fields && representation.IsDouble()) {
3833 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( 3815 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
3834 lookup->GetFieldIndex().field_index())); 3816 lookup->GetFieldIndex().field_index()));
3835 storage->set_value(value->Number()); 3817 storage->set_value(value->Number());
3836 return value; 3818 return;
3837 } 3819 }
3838 3820
3839 lookup->holder()->FastPropertyAtPut( 3821 lookup->holder()->FastPropertyAtPut(
3840 lookup->GetFieldIndex().field_index(), *value); 3822 lookup->GetFieldIndex().field_index(), *value);
3841 return value;
3842 } 3823 }
3843 3824
3844 3825
3845 static Handle<Object> ConvertAndSetLocalProperty( 3826 static void ConvertAndSetLocalProperty(LookupResult* lookup,
3846 LookupResult* lookup, 3827 Handle<Name> name,
3847 Handle<Name> name, 3828 Handle<Object> value,
3848 Handle<Object> value, 3829 PropertyAttributes attributes) {
3849 PropertyAttributes attributes) {
3850 Handle<JSObject> object(lookup->holder()); 3830 Handle<JSObject> object(lookup->holder());
3851 if (object->TooManyFastProperties()) { 3831 if (object->TooManyFastProperties()) {
3852 JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); 3832 JSObject::NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
3853 } 3833 }
3854 3834
3855 if (!object->HasFastProperties()) { 3835 if (!object->HasFastProperties()) {
3856 return ReplaceSlowProperty(object, name, value, attributes); 3836 ReplaceSlowProperty(object, name, value, attributes);
3837 return;
3857 } 3838 }
3858 3839
3859 int descriptor_index = lookup->GetDescriptorIndex(); 3840 int descriptor_index = lookup->GetDescriptorIndex();
3860 if (lookup->GetAttributes() == attributes) { 3841 if (lookup->GetAttributes() == attributes) {
3861 JSObject::GeneralizeFieldRepresentation( 3842 JSObject::GeneralizeFieldRepresentation(
3862 object, descriptor_index, Representation::Tagged(), FORCE_FIELD); 3843 object, descriptor_index, Representation::Tagged(), FORCE_FIELD);
3863 } else { 3844 } else {
3864 Handle<Map> old_map(object->map()); 3845 Handle<Map> old_map(object->map());
3865 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map, 3846 Handle<Map> new_map = Map::CopyGeneralizeAllRepresentations(old_map,
3866 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); 3847 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch");
3867 JSObject::MigrateToMap(object, new_map); 3848 JSObject::MigrateToMap(object, new_map);
3868 } 3849 }
3869 3850
3870 DescriptorArray* descriptors = object->map()->instance_descriptors(); 3851 DescriptorArray* descriptors = object->map()->instance_descriptors();
3871 int index = descriptors->GetDetails(descriptor_index).field_index(); 3852 int index = descriptors->GetDetails(descriptor_index).field_index();
3872 object->FastPropertyAtPut(index, *value); 3853 object->FastPropertyAtPut(index, *value);
3873 return value;
3874 } 3854 }
3875 3855
3876 3856
3877 static Handle<Object> SetPropertyToFieldWithAttributes( 3857 static void SetPropertyToFieldWithAttributes(LookupResult* lookup,
3878 LookupResult* lookup, 3858 Handle<Name> name,
3879 Handle<Name> name, 3859 Handle<Object> value,
3880 Handle<Object> value, 3860 PropertyAttributes attributes) {
3881 PropertyAttributes attributes) {
3882 if (lookup->GetAttributes() == attributes) { 3861 if (lookup->GetAttributes() == attributes) {
3883 if (value->IsUninitialized()) return value; 3862 if (value->IsUninitialized()) return;
3884 return SetPropertyToField(lookup, name, value); 3863 SetPropertyToField(lookup, name, value);
3885 } else { 3864 } else {
3886 return ConvertAndSetLocalProperty(lookup, name, value, attributes); 3865 ConvertAndSetLocalProperty(lookup, name, value, attributes);
3887 } 3866 }
3888 } 3867 }
3889 3868
3890 3869
3891 Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object, 3870 Handle<Object> JSObject::SetPropertyForResult(Handle<JSObject> object,
3892 LookupResult* lookup, 3871 LookupResult* lookup,
3893 Handle<Name> name, 3872 Handle<Name> name,
3894 Handle<Object> value, 3873 Handle<Object> value,
3895 PropertyAttributes attributes, 3874 PropertyAttributes attributes,
3896 StrictModeFlag strict_mode, 3875 StrictModeFlag strict_mode,
3897 StoreFromKeyed store_mode) { 3876 StoreFromKeyed store_mode) {
3898 Isolate* isolate = object->GetIsolate(); 3877 Isolate* isolate = object->GetIsolate();
3899 3878
3900 // Make sure that the top context does not change when doing callbacks or 3879 // Make sure that the top context does not change when doing callbacks or
3901 // interceptor calls. 3880 // interceptor calls.
3902 AssertNoContextChange ncc; 3881 AssertNoContextChange ncc;
3903 3882
3904 // Optimization for 2-byte strings often used as keys in a decompression 3883 // Optimization for 2-byte strings often used as keys in a decompression
3905 // dictionary. We internalize these short keys to avoid constantly 3884 // dictionary. We internalize these short keys to avoid constantly
3906 // reallocating them. 3885 // reallocating them.
3907 if (name->IsString() && !name->IsInternalizedString() && 3886 if (name->IsString() && !name->IsInternalizedString() &&
3908 Handle<String>::cast(name)->length() <= 2) { 3887 Handle<String>::cast(name)->length() <= 2) {
3909 name = isolate->factory()->InternalizeString(Handle<String>::cast(name)); 3888 name = isolate->factory()->InternalizeString(Handle<String>::cast(name));
3910 } 3889 }
3911 3890
3912 // Check access rights if needed. 3891 // Check access rights if needed.
3913 if (object->IsAccessCheckNeeded()) { 3892 if (object->IsAccessCheckNeeded()) {
3914 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { 3893 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) {
3915 CALL_HEAP_FUNCTION( 3894 return SetPropertyWithFailedAccessCheck(object, lookup, name, value,
3916 isolate, 3895 true, strict_mode);
3917 object->SetPropertyWithFailedAccessCheck(
3918 lookup, *name, *value, true, strict_mode),
3919 Object);
3920 } 3896 }
3921 } 3897 }
3922 3898
3923 if (object->IsJSGlobalProxy()) { 3899 if (object->IsJSGlobalProxy()) {
3924 Handle<Object> proto(object->GetPrototype(), isolate); 3900 Handle<Object> proto(object->GetPrototype(), isolate);
3925 if (proto->IsNull()) return value; 3901 if (proto->IsNull()) return value;
3926 ASSERT(proto->IsJSGlobalObject()); 3902 ASSERT(proto->IsJSGlobalObject());
3927 return SetPropertyForResult(Handle<JSObject>::cast(proto), 3903 return SetPropertyForResult(Handle<JSObject>::cast(proto),
3928 lookup, name, value, attributes, strict_mode, store_mode); 3904 lookup, name, value, attributes, strict_mode, store_mode);
3929 } 3905 }
(...skipping 30 matching lines...) Expand all
3960 if (FLAG_harmony_observation && 3936 if (FLAG_harmony_observation &&
3961 object->map()->is_observed() && lookup->IsDataProperty()) { 3937 object->map()->is_observed() && lookup->IsDataProperty()) {
3962 old_value = Object::GetProperty(object, name); 3938 old_value = Object::GetProperty(object, name);
3963 } 3939 }
3964 3940
3965 // This is a real property that is not read-only, or it is a 3941 // This is a real property that is not read-only, or it is a
3966 // transition or null descriptor and there are no setters in the prototypes. 3942 // transition or null descriptor and there are no setters in the prototypes.
3967 Handle<Object> result = value; 3943 Handle<Object> result = value;
3968 switch (lookup->type()) { 3944 switch (lookup->type()) {
3969 case NORMAL: 3945 case NORMAL:
3970 result = SetNormalizedProperty(handle(lookup->holder()), lookup, value); 3946 SetNormalizedProperty(handle(lookup->holder()), lookup, value);
3971 break; 3947 break;
3972 case FIELD: 3948 case FIELD:
3973 result = SetPropertyToField(lookup, name, value); 3949 SetPropertyToField(lookup, name, value);
3974 break; 3950 break;
3975 case CONSTANT: 3951 case CONSTANT:
3976 // Only replace the constant if necessary. 3952 // Only replace the constant if necessary.
3977 if (*value == lookup->GetConstant()) return value; 3953 if (*value == lookup->GetConstant()) return value;
3978 result = SetPropertyToField(lookup, name, value); 3954 SetPropertyToField(lookup, name, value);
3979 break; 3955 break;
3980 case CALLBACKS: { 3956 case CALLBACKS: {
3981 Handle<Object> callback_object(lookup->GetCallbackObject(), isolate); 3957 Handle<Object> callback_object(lookup->GetCallbackObject(), isolate);
3982 CALL_HEAP_FUNCTION( 3958 return SetPropertyWithCallback(object, callback_object, name, value,
3983 isolate, 3959 handle(lookup->holder()), strict_mode);
3984 object->SetPropertyWithCallback(*callback_object, *name, *value,
3985 lookup->holder(), strict_mode),
3986 Object);
3987 } 3960 }
3988 case INTERCEPTOR: 3961 case INTERCEPTOR:
3989 result = SetPropertyWithInterceptor(handle(lookup->holder()), name, value, 3962 result = SetPropertyWithInterceptor(handle(lookup->holder()), name, value,
3990 attributes, strict_mode); 3963 attributes, strict_mode);
3991 break; 3964 break;
3992 case TRANSITION: 3965 case TRANSITION:
3993 result = SetPropertyUsingTransition(handle(lookup->holder()), lookup, 3966 result = SetPropertyUsingTransition(handle(lookup->holder()), lookup,
3994 name, value, attributes); 3967 name, value, attributes);
3995 break; 3968 break;
3996 case HANDLER: 3969 case HANDLER:
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
4067 4040
4068 LookupResult lookup(isolate); 4041 LookupResult lookup(isolate);
4069 object->LocalLookup(*name, &lookup, true); 4042 object->LocalLookup(*name, &lookup, true);
4070 if (!lookup.IsFound()) { 4043 if (!lookup.IsFound()) {
4071 object->map()->LookupTransition(*object, *name, &lookup); 4044 object->map()->LookupTransition(*object, *name, &lookup);
4072 } 4045 }
4073 4046
4074 // Check access rights if needed. 4047 // Check access rights if needed.
4075 if (object->IsAccessCheckNeeded()) { 4048 if (object->IsAccessCheckNeeded()) {
4076 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { 4049 if (!isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) {
4077 CALL_HEAP_FUNCTION( 4050 return SetPropertyWithFailedAccessCheck(object, &lookup, name, value,
4078 isolate, 4051 false, kNonStrictMode);
4079 object->SetPropertyWithFailedAccessCheck(
4080 &lookup, *name, *value, false, kNonStrictMode),
4081 Object);
4082 } 4052 }
4083 } 4053 }
4084 4054
4085 if (object->IsJSGlobalProxy()) { 4055 if (object->IsJSGlobalProxy()) {
4086 Handle<Object> proto(object->GetPrototype(), isolate); 4056 Handle<Object> proto(object->GetPrototype(), isolate);
4087 if (proto->IsNull()) return value; 4057 if (proto->IsNull()) return value;
4088 ASSERT(proto->IsJSGlobalObject()); 4058 ASSERT(proto->IsJSGlobalObject());
4089 return SetLocalPropertyIgnoreAttributes(Handle<JSObject>::cast(proto), 4059 return SetLocalPropertyIgnoreAttributes(Handle<JSObject>::cast(proto),
4090 name, value, attributes, value_type, mode, extensibility_check); 4060 name, value, attributes, value_type, mode, extensibility_check);
4091 } 4061 }
(...skipping 13 matching lines...) Expand all
4105 Handle<Object> old_value = isolate->factory()->the_hole_value(); 4075 Handle<Object> old_value = isolate->factory()->the_hole_value();
4106 PropertyAttributes old_attributes = ABSENT; 4076 PropertyAttributes old_attributes = ABSENT;
4107 bool is_observed = FLAG_harmony_observation && object->map()->is_observed(); 4077 bool is_observed = FLAG_harmony_observation && object->map()->is_observed();
4108 if (is_observed && lookup.IsProperty()) { 4078 if (is_observed && lookup.IsProperty()) {
4109 if (lookup.IsDataProperty()) old_value = 4079 if (lookup.IsDataProperty()) old_value =
4110 Object::GetProperty(object, name); 4080 Object::GetProperty(object, name);
4111 old_attributes = lookup.GetAttributes(); 4081 old_attributes = lookup.GetAttributes();
4112 } 4082 }
4113 4083
4114 // Check of IsReadOnly removed from here in clone. 4084 // Check of IsReadOnly removed from here in clone.
4115 Handle<Object> result = value;
4116 switch (lookup.type()) { 4085 switch (lookup.type()) {
4117 case NORMAL: 4086 case NORMAL:
4118 result = ReplaceSlowProperty(object, name, value, attributes); 4087 ReplaceSlowProperty(object, name, value, attributes);
4119 break; 4088 break;
4120 case FIELD: 4089 case FIELD:
4121 result = SetPropertyToFieldWithAttributes( 4090 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes);
4122 &lookup, name, value, attributes);
4123 break; 4091 break;
4124 case CONSTANT: 4092 case CONSTANT:
4125 // Only replace the constant if necessary. 4093 // Only replace the constant if necessary.
4126 if (lookup.GetAttributes() != attributes || 4094 if (lookup.GetAttributes() != attributes ||
4127 *value != lookup.GetConstant()) { 4095 *value != lookup.GetConstant()) {
4128 result = SetPropertyToFieldWithAttributes( 4096 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes);
4129 &lookup, name, value, attributes);
4130 } 4097 }
4131 break; 4098 break;
4132 case CALLBACKS: 4099 case CALLBACKS:
4133 result = ConvertAndSetLocalProperty(&lookup, name, value, attributes); 4100 ConvertAndSetLocalProperty(&lookup, name, value, attributes);
4134 break; 4101 break;
4135 case TRANSITION: 4102 case TRANSITION: {
4136 result = SetPropertyUsingTransition(handle(lookup.holder()), &lookup, 4103 Handle<Object> result = SetPropertyUsingTransition(
4137 name, value, attributes); 4104 handle(lookup.holder()), &lookup, name, value, attributes);
4105 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>());
4138 break; 4106 break;
4107 }
4139 case NONEXISTENT: 4108 case NONEXISTENT:
4140 case HANDLER: 4109 case HANDLER:
4141 case INTERCEPTOR: 4110 case INTERCEPTOR:
4142 UNREACHABLE(); 4111 UNREACHABLE();
4143 } 4112 }
4144 4113
4145 if (result.is_null()) return result;
4146
4147 if (is_observed) { 4114 if (is_observed) {
4148 if (lookup.IsTransition()) { 4115 if (lookup.IsTransition()) {
4149 EnqueueChangeRecord(object, "new", name, old_value); 4116 EnqueueChangeRecord(object, "new", name, old_value);
4150 } else if (old_value->IsTheHole()) { 4117 } else if (old_value->IsTheHole()) {
4151 EnqueueChangeRecord(object, "reconfigured", name, old_value); 4118 EnqueueChangeRecord(object, "reconfigured", name, old_value);
4152 } else { 4119 } else {
4153 LookupResult new_lookup(isolate); 4120 LookupResult new_lookup(isolate);
4154 object->LocalLookup(*name, &new_lookup, true); 4121 object->LocalLookup(*name, &new_lookup, true);
4155 bool value_changed = false; 4122 bool value_changed = false;
4156 if (new_lookup.IsDataProperty()) { 4123 if (new_lookup.IsDataProperty()) {
4157 Handle<Object> new_value = Object::GetProperty(object, name); 4124 Handle<Object> new_value = Object::GetProperty(object, name);
4158 value_changed = !old_value->SameValue(*new_value); 4125 value_changed = !old_value->SameValue(*new_value);
4159 } 4126 }
4160 if (new_lookup.GetAttributes() != old_attributes) { 4127 if (new_lookup.GetAttributes() != old_attributes) {
4161 if (!value_changed) old_value = isolate->factory()->the_hole_value(); 4128 if (!value_changed) old_value = isolate->factory()->the_hole_value();
4162 EnqueueChangeRecord(object, "reconfigured", name, old_value); 4129 EnqueueChangeRecord(object, "reconfigured", name, old_value);
4163 } else if (value_changed) { 4130 } else if (value_changed) {
4164 EnqueueChangeRecord(object, "updated", name, old_value); 4131 EnqueueChangeRecord(object, "updated", name, old_value);
4165 } 4132 }
4166 } 4133 }
4167 } 4134 }
4168 4135
4169 return result; 4136 return value;
4170 } 4137 }
4171 4138
4172 4139
4173 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor( 4140 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor(
4174 JSObject* receiver, 4141 JSObject* receiver,
4175 Name* name, 4142 Name* name,
4176 bool continue_search) { 4143 bool continue_search) {
4177 // Check local property, ignore interceptor. 4144 // Check local property, ignore interceptor.
4178 LookupResult result(GetIsolate()); 4145 LookupResult result(GetIsolate());
4179 LocalLookupRealNamedProperty(name, &result); 4146 LocalLookupRealNamedProperty(name, &result);
(...skipping 7529 matching lines...) Expand 10 before | Expand all | Expand 10 after
11709 return GetDeclaredAccessorProperty(receiver, 11676 return GetDeclaredAccessorProperty(receiver,
11710 DeclaredAccessorInfo::cast(structure), 11677 DeclaredAccessorInfo::cast(structure),
11711 isolate); 11678 isolate);
11712 } 11679 }
11713 11680
11714 UNREACHABLE(); 11681 UNREACHABLE();
11715 return NULL; 11682 return NULL;
11716 } 11683 }
11717 11684
11718 11685
11719 MaybeObject* JSObject::SetElementWithCallback(Object* structure, 11686 Handle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object,
11720 uint32_t index, 11687 Handle<Object> structure,
11721 Object* value, 11688 uint32_t index,
11722 JSObject* holder, 11689 Handle<Object> value,
11723 StrictModeFlag strict_mode) { 11690 Handle<JSObject> holder,
11724 Isolate* isolate = GetIsolate(); 11691 StrictModeFlag strict_mode) {
11725 HandleScope scope(isolate); 11692 Isolate* isolate = object->GetIsolate();
11726 11693
11727 // We should never get here to initialize a const with the hole 11694 // We should never get here to initialize a const with the hole
11728 // value since a const declaration would conflict with the setter. 11695 // value since a const declaration would conflict with the setter.
11729 ASSERT(!value->IsTheHole()); 11696 ASSERT(!value->IsTheHole());
11730 Handle<Object> value_handle(value, isolate);
11731 11697
11732 // To accommodate both the old and the new api we switch on the 11698 // To accommodate both the old and the new api we switch on the
11733 // data structure used to store the callbacks. Eventually foreign 11699 // data structure used to store the callbacks. Eventually foreign
11734 // callbacks should be phased out. 11700 // callbacks should be phased out.
11735 ASSERT(!structure->IsForeign()); 11701 ASSERT(!structure->IsForeign());
11736 11702
11737 if (structure->IsExecutableAccessorInfo()) { 11703 if (structure->IsExecutableAccessorInfo()) {
11738 // api style callbacks 11704 // api style callbacks
11739 Handle<JSObject> self(this); 11705 Handle<ExecutableAccessorInfo> data =
11740 Handle<JSObject> holder_handle(JSObject::cast(holder)); 11706 Handle<ExecutableAccessorInfo>::cast(structure);
11741 Handle<ExecutableAccessorInfo> data(
11742 ExecutableAccessorInfo::cast(structure));
11743 Object* call_obj = data->setter(); 11707 Object* call_obj = data->setter();
11744 v8::AccessorSetterCallback call_fun = 11708 v8::AccessorSetterCallback call_fun =
11745 v8::ToCData<v8::AccessorSetterCallback>(call_obj); 11709 v8::ToCData<v8::AccessorSetterCallback>(call_obj);
11746 if (call_fun == NULL) return value; 11710 if (call_fun == NULL) return value;
11747 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 11711 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
11748 Handle<String> key(isolate->factory()->NumberToString(number)); 11712 Handle<String> key(isolate->factory()->NumberToString(number));
11749 LOG(isolate, ApiNamedPropertyAccess("store", *self, *key)); 11713 LOG(isolate, ApiNamedPropertyAccess("store", *object, *key));
11750 PropertyCallbackArguments 11714 PropertyCallbackArguments
11751 args(isolate, data->data(), *self, *holder_handle); 11715 args(isolate, data->data(), *object, *holder);
11752 args.Call(call_fun, 11716 args.Call(call_fun,
11753 v8::Utils::ToLocal(key), 11717 v8::Utils::ToLocal(key),
11754 v8::Utils::ToLocal(value_handle)); 11718 v8::Utils::ToLocal(value));
11755 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 11719 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
11756 return *value_handle; 11720 return value;
11757 } 11721 }
11758 11722
11759 if (structure->IsAccessorPair()) { 11723 if (structure->IsAccessorPair()) {
11760 Handle<Object> setter(AccessorPair::cast(structure)->setter(), isolate); 11724 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
11761 if (setter->IsSpecFunction()) { 11725 if (setter->IsSpecFunction()) {
11762 // TODO(rossberg): nicer would be to cast to some JSCallable here... 11726 // TODO(rossberg): nicer would be to cast to some JSCallable here...
11763 return SetPropertyWithDefinedSetter(JSReceiver::cast(*setter), value); 11727 CALL_HEAP_FUNCTION(isolate,
11728 object->SetPropertyWithDefinedSetter(
11729 JSReceiver::cast(*setter), *value),
11730 Object);
11764 } else { 11731 } else {
11765 if (strict_mode == kNonStrictMode) { 11732 if (strict_mode == kNonStrictMode) {
11766 return value; 11733 return value;
11767 } 11734 }
11768 Handle<Object> holder_handle(holder, isolate);
11769 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); 11735 Handle<Object> key(isolate->factory()->NewNumberFromUint(index));
11770 Handle<Object> args[2] = { key, holder_handle }; 11736 Handle<Object> args[2] = { key, holder };
11771 return isolate->Throw( 11737 Handle<Object> error = isolate->factory()->NewTypeError(
11772 *isolate->factory()->NewTypeError("no_setter_in_callback", 11738 "no_setter_in_callback", HandleVector(args, 2));
11773 HandleVector(args, 2))); 11739 isolate->Throw(*error);
11740 return Handle<Object>();
11774 } 11741 }
11775 } 11742 }
11776 11743
11777 // TODO(dcarney): Handle correctly. 11744 // TODO(dcarney): Handle correctly.
11778 if (structure->IsDeclaredAccessorInfo()) return value; 11745 if (structure->IsDeclaredAccessorInfo()) return value;
11779 11746
11780 UNREACHABLE(); 11747 UNREACHABLE();
11781 return NULL; 11748 return Handle<Object>();
11782 } 11749 }
11783 11750
11784 11751
11785 bool JSObject::HasFastArgumentsElements() { 11752 bool JSObject::HasFastArgumentsElements() {
11786 Heap* heap = GetHeap(); 11753 Heap* heap = GetHeap();
11787 if (!elements()->IsFixedArray()) return false; 11754 if (!elements()->IsFixedArray()) return false;
11788 FixedArray* elements = FixedArray::cast(this->elements()); 11755 FixedArray* elements = FixedArray::cast(this->elements());
11789 if (elements->map() != heap->non_strict_arguments_elements_map()) { 11756 if (elements->map() != heap->non_strict_arguments_elements_map()) {
11790 return false; 11757 return false;
11791 } 11758 }
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
11968 // Insert element in the dictionary. 11935 // Insert element in the dictionary.
11969 Handle<FixedArray> elements(FixedArray::cast(this->elements())); 11936 Handle<FixedArray> elements(FixedArray::cast(this->elements()));
11970 bool is_arguments = 11937 bool is_arguments =
11971 (elements->map() == heap->non_strict_arguments_elements_map()); 11938 (elements->map() == heap->non_strict_arguments_elements_map());
11972 Handle<SeededNumberDictionary> dictionary(is_arguments 11939 Handle<SeededNumberDictionary> dictionary(is_arguments
11973 ? SeededNumberDictionary::cast(elements->get(1)) 11940 ? SeededNumberDictionary::cast(elements->get(1))
11974 : SeededNumberDictionary::cast(*elements)); 11941 : SeededNumberDictionary::cast(*elements));
11975 11942
11976 int entry = dictionary->FindEntry(index); 11943 int entry = dictionary->FindEntry(index);
11977 if (entry != SeededNumberDictionary::kNotFound) { 11944 if (entry != SeededNumberDictionary::kNotFound) {
11978 Object* element = dictionary->ValueAt(entry); 11945 Handle<Object> element(dictionary->ValueAt(entry), isolate);
11979 PropertyDetails details = dictionary->DetailsAt(entry); 11946 PropertyDetails details = dictionary->DetailsAt(entry);
11980 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { 11947 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) {
11981 return SetElementWithCallback(element, index, *value, this, strict_mode); 11948 Handle<Object> result = SetElementWithCallback(self, element, index,
11949 value, self, strict_mode);
11950 RETURN_IF_EMPTY_HANDLE(isolate, result);
11951 return *result;
11982 } else { 11952 } else {
11983 dictionary->UpdateMaxNumberKey(index); 11953 dictionary->UpdateMaxNumberKey(index);
11984 // If a value has not been initialized we allow writing to it even if it 11954 // If a value has not been initialized we allow writing to it even if it
11985 // is read-only (a declared const that has not been initialized). If a 11955 // is read-only (a declared const that has not been initialized). If a
11986 // value is being defined we skip attribute checks completely. 11956 // value is being defined we skip attribute checks completely.
11987 if (set_mode == DEFINE_PROPERTY) { 11957 if (set_mode == DEFINE_PROPERTY) {
11988 details = PropertyDetails( 11958 details = PropertyDetails(
11989 attributes, NORMAL, details.dictionary_index()); 11959 attributes, NORMAL, details.dictionary_index());
11990 dictionary->DetailsAtPut(entry, details); 11960 dictionary->DetailsAtPut(entry, details);
11991 } else if (details.IsReadOnly() && !element->IsTheHole()) { 11961 } else if (details.IsReadOnly() && !element->IsTheHole()) {
11992 if (strict_mode == kNonStrictMode) { 11962 if (strict_mode == kNonStrictMode) {
11993 return isolate->heap()->undefined_value(); 11963 return isolate->heap()->undefined_value();
11994 } else { 11964 } else {
11995 Handle<Object> holder(this, isolate); 11965 Handle<Object> holder(this, isolate);
11996 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 11966 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
11997 Handle<Object> args[2] = { number, holder }; 11967 Handle<Object> args[2] = { number, holder };
11998 Handle<Object> error = 11968 Handle<Object> error =
11999 isolate->factory()->NewTypeError("strict_read_only_property", 11969 isolate->factory()->NewTypeError("strict_read_only_property",
12000 HandleVector(args, 2)); 11970 HandleVector(args, 2));
12001 return isolate->Throw(*error); 11971 return isolate->Throw(*error);
12002 } 11972 }
12003 } 11973 }
12004 // Elements of the arguments object in slow mode might be slow aliases. 11974 // Elements of the arguments object in slow mode might be slow aliases.
12005 if (is_arguments && element->IsAliasedArgumentsEntry()) { 11975 if (is_arguments && element->IsAliasedArgumentsEntry()) {
12006 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(element); 11976 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*element);
12007 Context* context = Context::cast(elements->get(0)); 11977 Context* context = Context::cast(elements->get(0));
12008 int context_index = entry->aliased_context_slot(); 11978 int context_index = entry->aliased_context_slot();
12009 ASSERT(!context->get(context_index)->IsTheHole()); 11979 ASSERT(!context->get(context_index)->IsTheHole());
12010 context->set(context_index, *value); 11980 context->set(context_index, *value);
12011 // For elements that are still writable we keep slow aliasing. 11981 // For elements that are still writable we keep slow aliasing.
12012 if (!details.IsReadOnly()) value = handle(element, isolate); 11982 if (!details.IsReadOnly()) value = element;
12013 } 11983 }
12014 dictionary->ValueAtPut(entry, *value); 11984 dictionary->ValueAtPut(entry, *value);
12015 } 11985 }
12016 } else { 11986 } else {
12017 // Index not already used. Look for an accessor in the prototype chain. 11987 // Index not already used. Look for an accessor in the prototype chain.
12018 // Can cause GC! 11988 // Can cause GC!
12019 if (check_prototype) { 11989 if (check_prototype) {
12020 bool found; 11990 bool found;
12021 MaybeObject* result = SetElementWithCallbackSetterInPrototypes( 11991 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(
12022 index, *value, &found, strict_mode); 11992 index, *value, &found, strict_mode);
(...skipping 4119 matching lines...) Expand 10 before | Expand all | Expand 10 after
16142 #define ERROR_MESSAGES_TEXTS(C, T) T, 16112 #define ERROR_MESSAGES_TEXTS(C, T) T,
16143 static const char* error_messages_[] = { 16113 static const char* error_messages_[] = {
16144 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16114 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16145 }; 16115 };
16146 #undef ERROR_MESSAGES_TEXTS 16116 #undef ERROR_MESSAGES_TEXTS
16147 return error_messages_[reason]; 16117 return error_messages_[reason];
16148 } 16118 }
16149 16119
16150 16120
16151 } } // namespace v8::internal 16121 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698