OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |