| 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 2152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2163 MaybeObject* result_object = | 2163 MaybeObject* result_object = |
| 2164 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); | 2164 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); |
| 2165 if (done) return result_object; | 2165 if (done) return result_object; |
| 2166 // Add a new real property. | 2166 // Add a new real property. |
| 2167 return AddProperty(name, value, attributes, strict_mode, | 2167 return AddProperty(name, value, attributes, strict_mode, |
| 2168 MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK, | 2168 MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK, |
| 2169 OPTIMAL_REPRESENTATION, mode); | 2169 OPTIMAL_REPRESENTATION, mode); |
| 2170 } | 2170 } |
| 2171 | 2171 |
| 2172 | 2172 |
| 2173 MaybeObject* JSObject::ReplaceSlowProperty(Name* name, | 2173 void JSObject::ReplaceSlowProperty(Handle<JSObject> object, |
| 2174 Object* value, | 2174 Handle<Name> name, |
| 2175 PropertyAttributes attributes) { | 2175 Handle<Object> value, |
| 2176 NameDictionary* dictionary = property_dictionary(); | 2176 PropertyAttributes attributes) { |
| 2177 int old_index = dictionary->FindEntry(name); | 2177 Handle<NameDictionary> dictionary(object->property_dictionary()); |
| 2178 int old_index = dictionary->FindEntry(*name); |
| 2178 int new_enumeration_index = 0; // 0 means "Use the next available index." | 2179 int new_enumeration_index = 0; // 0 means "Use the next available index." |
| 2179 if (old_index != -1) { | 2180 if (old_index != -1) { |
| 2180 // All calls to ReplaceSlowProperty have had all transitions removed. | 2181 // All calls to ReplaceSlowProperty have had all transitions removed. |
| 2181 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index(); | 2182 new_enumeration_index = dictionary->DetailsAt(old_index).dictionary_index(); |
| 2182 } | 2183 } |
| 2183 | 2184 |
| 2184 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); | 2185 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); |
| 2185 return SetNormalizedProperty(name, value, new_details); | 2186 SetNormalizedProperty(object, name, value, new_details); |
| 2186 } | 2187 } |
| 2187 | 2188 |
| 2188 | 2189 |
| 2189 const char* Representation::Mnemonic() const { | 2190 const char* Representation::Mnemonic() const { |
| 2190 switch (kind_) { | 2191 switch (kind_) { |
| 2191 case kNone: return "v"; | 2192 case kNone: return "v"; |
| 2192 case kTagged: return "t"; | 2193 case kTagged: return "t"; |
| 2193 case kSmi: return "s"; | 2194 case kSmi: return "s"; |
| 2194 case kDouble: return "d"; | 2195 case kDouble: return "d"; |
| 2195 case kInteger32: return "i"; | 2196 case kInteger32: return "i"; |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2383 RightTrimFixedArray<FROM_MUTATOR>(heap, array, inobject); | 2384 RightTrimFixedArray<FROM_MUTATOR>(heap, array, inobject); |
| 2384 set_properties(array); | 2385 set_properties(array); |
| 2385 } | 2386 } |
| 2386 | 2387 |
| 2387 set_map(new_map); | 2388 set_map(new_map); |
| 2388 | 2389 |
| 2389 return this; | 2390 return this; |
| 2390 } | 2391 } |
| 2391 | 2392 |
| 2392 | 2393 |
| 2394 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, |
| 2395 int modify_index, |
| 2396 Representation new_representation, |
| 2397 StoreMode store_mode) { |
| 2398 CALL_HEAP_FUNCTION_VOID( |
| 2399 object->GetIsolate(), |
| 2400 object->GeneralizeFieldRepresentation( |
| 2401 modify_index, new_representation, store_mode)); |
| 2402 } |
| 2403 |
| 2404 |
| 2393 MaybeObject* JSObject::GeneralizeFieldRepresentation( | 2405 MaybeObject* JSObject::GeneralizeFieldRepresentation( |
| 2394 int modify_index, | 2406 int modify_index, |
| 2395 Representation new_representation, | 2407 Representation new_representation, |
| 2396 StoreMode store_mode) { | 2408 StoreMode store_mode) { |
| 2397 Map* new_map; | 2409 Map* new_map; |
| 2398 MaybeObject* maybe_new_map = map()->GeneralizeRepresentation( | 2410 MaybeObject* maybe_new_map = map()->GeneralizeRepresentation( |
| 2399 modify_index, new_representation, store_mode); | 2411 modify_index, new_representation, store_mode); |
| 2400 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | 2412 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| 2401 if (map() == new_map) return this; | 2413 if (map() == new_map) return this; |
| 2402 | 2414 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2446 PrintGeneralization(stdout, reason, modify_index, | 2458 PrintGeneralization(stdout, reason, modify_index, |
| 2447 new_map->NumberOfOwnDescriptors(), | 2459 new_map->NumberOfOwnDescriptors(), |
| 2448 new_map->NumberOfOwnDescriptors(), | 2460 new_map->NumberOfOwnDescriptors(), |
| 2449 details.type() == CONSTANT && store_mode == FORCE_FIELD, | 2461 details.type() == CONSTANT && store_mode == FORCE_FIELD, |
| 2450 Representation::Tagged(), Representation::Tagged()); | 2462 Representation::Tagged(), Representation::Tagged()); |
| 2451 } | 2463 } |
| 2452 return new_map; | 2464 return new_map; |
| 2453 } | 2465 } |
| 2454 | 2466 |
| 2455 | 2467 |
| 2468 Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, |
| 2469 int descriptor_index, |
| 2470 StoreMode store_mode, |
| 2471 PropertyAttributes attributes, |
| 2472 const char* reason) { |
| 2473 CALL_HEAP_FUNCTION(map->GetIsolate(), |
| 2474 map->CopyGeneralizeAllRepresentations( |
| 2475 descriptor_index, store_mode, attributes, reason), |
| 2476 Map); |
| 2477 } |
| 2478 |
| 2479 |
| 2456 void Map::DeprecateTransitionTree() { | 2480 void Map::DeprecateTransitionTree() { |
| 2457 if (!FLAG_track_fields) return; | 2481 if (!FLAG_track_fields) return; |
| 2458 if (is_deprecated()) return; | 2482 if (is_deprecated()) return; |
| 2459 if (HasTransitionArray()) { | 2483 if (HasTransitionArray()) { |
| 2460 TransitionArray* transitions = this->transitions(); | 2484 TransitionArray* transitions = this->transitions(); |
| 2461 for (int i = 0; i < transitions->number_of_transitions(); i++) { | 2485 for (int i = 0; i < transitions->number_of_transitions(); i++) { |
| 2462 transitions->GetTarget(i)->DeprecateTransitionTree(); | 2486 transitions->GetTarget(i)->DeprecateTransitionTree(); |
| 2463 } | 2487 } |
| 2464 } | 2488 } |
| 2465 deprecate(); | 2489 deprecate(); |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2725 int valid = updated->NumberOfOwnDescriptors(); | 2749 int valid = updated->NumberOfOwnDescriptors(); |
| 2726 if (!updated_descriptors->IsMoreGeneralThan( | 2750 if (!updated_descriptors->IsMoreGeneralThan( |
| 2727 verbatim, valid, descriptors, old_descriptors)) { | 2751 verbatim, valid, descriptors, old_descriptors)) { |
| 2728 return NULL; | 2752 return NULL; |
| 2729 } | 2753 } |
| 2730 | 2754 |
| 2731 return updated; | 2755 return updated; |
| 2732 } | 2756 } |
| 2733 | 2757 |
| 2734 | 2758 |
| 2759 Handle<Object> JSObject::SetPropertyWithInterceptor( |
| 2760 Handle<JSObject> object, |
| 2761 Handle<Name> name, |
| 2762 Handle<Object> value, |
| 2763 PropertyAttributes attributes, |
| 2764 StrictModeFlag strict_mode) { |
| 2765 CALL_HEAP_FUNCTION( |
| 2766 object->GetIsolate(), |
| 2767 object->SetPropertyWithInterceptor( |
| 2768 *name, *value, attributes, strict_mode), |
| 2769 Object); |
| 2770 } |
| 2771 |
| 2772 |
| 2735 MaybeObject* JSObject::SetPropertyWithInterceptor( | 2773 MaybeObject* JSObject::SetPropertyWithInterceptor( |
| 2736 Name* name, | 2774 Name* name, |
| 2737 Object* value, | 2775 Object* value, |
| 2738 PropertyAttributes attributes, | 2776 PropertyAttributes attributes, |
| 2739 StrictModeFlag strict_mode) { | 2777 StrictModeFlag strict_mode) { |
| 2740 // TODO(rossberg): Support symbols in the API. | 2778 // TODO(rossberg): Support symbols in the API. |
| 2741 if (name->IsSymbol()) return value; | 2779 if (name->IsSymbol()) return value; |
| 2742 Isolate* isolate = GetIsolate(); | 2780 Isolate* isolate = GetIsolate(); |
| 2743 HandleScope scope(isolate); | 2781 HandleScope scope(isolate); |
| 2744 Handle<JSObject> this_handle(this); | 2782 Handle<JSObject> this_handle(this); |
| (...skipping 985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3730 int modify_index, | 3768 int modify_index, |
| 3731 Representation representation, | 3769 Representation representation, |
| 3732 StoreMode store_mode) { | 3770 StoreMode store_mode) { |
| 3733 CALL_HEAP_FUNCTION( | 3771 CALL_HEAP_FUNCTION( |
| 3734 map->GetIsolate(), | 3772 map->GetIsolate(), |
| 3735 map->GeneralizeRepresentation(modify_index, representation, store_mode), | 3773 map->GeneralizeRepresentation(modify_index, representation, store_mode), |
| 3736 Map); | 3774 Map); |
| 3737 } | 3775 } |
| 3738 | 3776 |
| 3739 | 3777 |
| 3740 static MaybeObject* SetPropertyUsingTransition(LookupResult* lookup, | 3778 void JSObject::AddProperty(Handle<JSObject> object, |
| 3741 Handle<Name> name, | 3779 Handle<Name> name, |
| 3742 Handle<Object> value, | 3780 Handle<Object> value, |
| 3743 PropertyAttributes attributes) { | 3781 PropertyAttributes attributes, |
| 3744 Map* transition_map = lookup->GetTransitionTarget(); | 3782 StrictModeFlag strict_mode, |
| 3783 StoreFromKeyed store_mode, |
| 3784 ExtensibilityCheck extensibility_check, |
| 3785 ValueType value_type, |
| 3786 StoreMode mode, |
| 3787 TransitionFlag flag) { |
| 3788 CALL_HEAP_FUNCTION_VOID( |
| 3789 object->GetIsolate(), |
| 3790 object->AddProperty(*name, *value, attributes, strict_mode, store_mode, |
| 3791 extensibility_check, value_type, mode, flag)); |
| 3792 } |
| 3793 |
| 3794 |
| 3795 void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> map) { |
| 3796 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), object->MigrateToMap(*map)); |
| 3797 } |
| 3798 |
| 3799 |
| 3800 void JSObject::AddFastPropertyUsingMap(Handle<JSObject> object, |
| 3801 Handle<Map> new_map, |
| 3802 Handle<Name> name, |
| 3803 Handle<Object> value, |
| 3804 int field_index, |
| 3805 Representation representation) { |
| 3806 CALL_HEAP_FUNCTION_VOID( |
| 3807 object->GetIsolate(), |
| 3808 object->AddFastPropertyUsingMap( |
| 3809 *new_map, *name, *value, field_index, representation)); |
| 3810 } |
| 3811 |
| 3812 |
| 3813 void JSObject::SetPropertyUsingTransition(LookupResult* lookup, |
| 3814 Handle<Name> name, |
| 3815 Handle<Object> value, |
| 3816 PropertyAttributes attributes) { |
| 3817 Handle<JSObject> holder(lookup->holder()); |
| 3818 Handle<Map> transition_map(lookup->GetTransitionTarget()); |
| 3745 int descriptor = transition_map->LastAdded(); | 3819 int descriptor = transition_map->LastAdded(); |
| 3746 | 3820 |
| 3747 DescriptorArray* descriptors = transition_map->instance_descriptors(); | 3821 Handle<DescriptorArray> descriptors(transition_map->instance_descriptors()); |
| 3748 PropertyDetails details = descriptors->GetDetails(descriptor); | 3822 PropertyDetails details = descriptors->GetDetails(descriptor); |
| 3749 | 3823 |
| 3750 if (details.type() == CALLBACKS || attributes != details.attributes()) { | 3824 if (details.type() == CALLBACKS || attributes != details.attributes()) { |
| 3751 // AddProperty will either normalize the object, or create a new fast copy | 3825 // AddProperty will either normalize the object, or create a new fast copy |
| 3752 // of the map. If we get a fast copy of the map, all field representations | 3826 // of the map. If we get a fast copy of the map, all field representations |
| 3753 // will be tagged since the transition is omitted. | 3827 // will be tagged since the transition is omitted. |
| 3754 return lookup->holder()->AddProperty( | 3828 AddProperty(holder, name, value, attributes, kNonStrictMode, |
| 3755 *name, *value, attributes, kNonStrictMode, | 3829 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, |
| 3756 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, | 3830 JSReceiver::OMIT_EXTENSIBILITY_CHECK, |
| 3757 JSReceiver::OMIT_EXTENSIBILITY_CHECK, | 3831 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); |
| 3758 JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); | 3832 return; |
| 3759 } | 3833 } |
| 3760 | 3834 |
| 3761 // Keep the target CONSTANT if the same value is stored. | 3835 // Keep the target CONSTANT if the same value is stored. |
| 3762 // TODO(verwaest): Also support keeping the placeholder | 3836 // TODO(verwaest): Also support keeping the placeholder |
| 3763 // (value->IsUninitialized) as constant. | 3837 // (value->IsUninitialized) as constant. |
| 3764 if (details.type() == CONSTANT && | 3838 if (details.type() == CONSTANT && |
| 3765 descriptors->GetValue(descriptor) == *value) { | 3839 descriptors->GetValue(descriptor) == *value) { |
| 3766 lookup->holder()->set_map(transition_map); | 3840 holder->set_map(*transition_map); |
| 3767 return *value; | 3841 return; |
| 3768 } | 3842 } |
| 3769 | 3843 |
| 3770 Representation representation = details.representation(); | 3844 Representation representation = details.representation(); |
| 3771 | 3845 |
| 3772 if (!value->FitsRepresentation(representation) || | 3846 if (!value->FitsRepresentation(representation) || |
| 3773 details.type() == CONSTANT) { | 3847 details.type() == CONSTANT) { |
| 3774 MaybeObject* maybe_map = transition_map->GeneralizeRepresentation( | 3848 transition_map = Map::GeneralizeRepresentation( |
| 3775 descriptor, value->OptimalRepresentation(), FORCE_FIELD); | 3849 transition_map, descriptor, |
| 3776 if (!maybe_map->To(&transition_map)) return maybe_map; | 3850 value->OptimalRepresentation(), FORCE_FIELD); |
| 3777 Object* back = transition_map->GetBackPointer(); | 3851 Handle<Object> back(transition_map->GetBackPointer(), |
| 3852 transition_map->GetIsolate()); |
| 3778 if (back->IsMap()) { | 3853 if (back->IsMap()) { |
| 3779 MaybeObject* maybe_failure = | 3854 MigrateToMap(holder, Handle<Map>::cast(back)); |
| 3780 lookup->holder()->MigrateToMap(Map::cast(back)); | |
| 3781 if (maybe_failure->IsFailure()) return maybe_failure; | |
| 3782 } | 3855 } |
| 3783 descriptors = transition_map->instance_descriptors(); | 3856 descriptors = handle(transition_map->instance_descriptors()); |
| 3784 representation = descriptors->GetDetails(descriptor).representation(); | 3857 representation = descriptors->GetDetails(descriptor).representation(); |
| 3785 } | 3858 } |
| 3786 | 3859 |
| 3787 int field_index = descriptors->GetFieldIndex(descriptor); | 3860 int field_index = descriptors->GetFieldIndex(descriptor); |
| 3788 return lookup->holder()->AddFastPropertyUsingMap( | 3861 return AddFastPropertyUsingMap( |
| 3789 transition_map, *name, *value, field_index, representation); | 3862 holder, transition_map, name, value, field_index, representation); |
| 3790 } | 3863 } |
| 3791 | 3864 |
| 3792 | 3865 |
| 3793 static MaybeObject* SetPropertyToField(LookupResult* lookup, | 3866 void JSObject::SetPropertyToField(LookupResult* lookup, |
| 3794 Handle<Name> name, | 3867 Handle<Name> name, |
| 3795 Handle<Object> value) { | 3868 Handle<Object> value) { |
| 3869 Handle<JSObject> holder(lookup->holder()); |
| 3796 Representation representation = lookup->representation(); | 3870 Representation representation = lookup->representation(); |
| 3871 |
| 3797 if (!value->FitsRepresentation(representation) || | 3872 if (!value->FitsRepresentation(representation) || |
| 3798 lookup->type() == CONSTANT) { | 3873 lookup->type() == CONSTANT) { |
| 3799 MaybeObject* maybe_failure = | 3874 GeneralizeFieldRepresentation( |
| 3800 lookup->holder()->GeneralizeFieldRepresentation( | 3875 holder, lookup->GetDescriptorIndex(), |
| 3801 lookup->GetDescriptorIndex(), | 3876 value->OptimalRepresentation(), FORCE_FIELD); |
| 3802 value->OptimalRepresentation(), | 3877 DescriptorArray* desc = holder->map()->instance_descriptors(); |
| 3803 FORCE_FIELD); | |
| 3804 if (maybe_failure->IsFailure()) return maybe_failure; | |
| 3805 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); | |
| 3806 int descriptor = lookup->GetDescriptorIndex(); | 3878 int descriptor = lookup->GetDescriptorIndex(); |
| 3807 representation = desc->GetDetails(descriptor).representation(); | 3879 representation = desc->GetDetails(descriptor).representation(); |
| 3808 } | 3880 } |
| 3809 | 3881 |
| 3882 int field_index = lookup->GetFieldIndex().field_index(); |
| 3810 if (FLAG_track_double_fields && representation.IsDouble()) { | 3883 if (FLAG_track_double_fields && representation.IsDouble()) { |
| 3811 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( | 3884 Handle<HeapNumber> storage( |
| 3812 lookup->GetFieldIndex().field_index())); | 3885 HeapNumber::cast(holder->RawFastPropertyAt(field_index))); |
| 3813 storage->set_value(value->Number()); | 3886 storage->set_value(value->Number()); |
| 3814 return *value; | 3887 return; |
| 3815 } | 3888 } |
| 3816 | 3889 |
| 3817 lookup->holder()->FastPropertyAtPut( | 3890 holder->FastPropertyAtPut(field_index, *value); |
| 3818 lookup->GetFieldIndex().field_index(), *value); | |
| 3819 return *value; | |
| 3820 } | 3891 } |
| 3821 | 3892 |
| 3822 | 3893 |
| 3823 static MaybeObject* ConvertAndSetLocalProperty(LookupResult* lookup, | 3894 void JSObject::ConvertAndSetLocalProperty(LookupResult* lookup, |
| 3824 Name* name, | 3895 Handle<Name> name, |
| 3825 Object* value, | 3896 Handle<Object> value, |
| 3826 PropertyAttributes attributes) { | 3897 PropertyAttributes attributes) { |
| 3827 JSObject* object = lookup->holder(); | 3898 Handle<JSObject> object(lookup->holder()); |
| 3828 if (object->TooManyFastProperties()) { | 3899 if (object->TooManyFastProperties()) { |
| 3829 MaybeObject* maybe_failure = object->NormalizeProperties( | 3900 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
| 3830 CLEAR_INOBJECT_PROPERTIES, 0); | |
| 3831 if (maybe_failure->IsFailure()) return maybe_failure; | |
| 3832 } | 3901 } |
| 3833 | 3902 |
| 3834 if (!object->HasFastProperties()) { | 3903 if (!object->HasFastProperties()) { |
| 3835 return object->ReplaceSlowProperty(name, value, attributes); | 3904 ReplaceSlowProperty(object, name, value, attributes); |
| 3905 return; |
| 3836 } | 3906 } |
| 3837 | 3907 |
| 3838 int descriptor_index = lookup->GetDescriptorIndex(); | 3908 int descriptor_index = lookup->GetDescriptorIndex(); |
| 3839 if (lookup->GetAttributes() == attributes) { | 3909 if (lookup->GetAttributes() == attributes) { |
| 3840 MaybeObject* maybe_failure = object->GeneralizeFieldRepresentation( | 3910 GeneralizeFieldRepresentation( |
| 3841 descriptor_index, Representation::Tagged(), FORCE_FIELD); | 3911 object, descriptor_index, Representation::Tagged(), FORCE_FIELD); |
| 3842 if (maybe_failure->IsFailure()) return maybe_failure; | |
| 3843 } else { | 3912 } else { |
| 3844 Map* map; | 3913 Handle<Map> map = Map::CopyGeneralizeAllRepresentations( |
| 3845 MaybeObject* maybe_map = object->map()->CopyGeneralizeAllRepresentations( | 3914 handle(object->map()), descriptor_index, FORCE_FIELD, |
| 3846 descriptor_index, FORCE_FIELD, attributes, "attributes mismatch"); | 3915 attributes, "attributes mismatch"); |
| 3847 if (!maybe_map->To(&map)) return maybe_map; | 3916 MigrateToMap(object, map); |
| 3848 MaybeObject* maybe_failure = object->MigrateToMap(map); | |
| 3849 if (maybe_failure->IsFailure()) return maybe_failure; | |
| 3850 } | 3917 } |
| 3851 | 3918 |
| 3852 DescriptorArray* descriptors = object->map()->instance_descriptors(); | 3919 DescriptorArray* descriptors = object->map()->instance_descriptors(); |
| 3853 int index = descriptors->GetDetails(descriptor_index).field_index(); | 3920 int index = descriptors->GetDetails(descriptor_index).field_index(); |
| 3854 object->FastPropertyAtPut(index, value); | 3921 object->FastPropertyAtPut(index, *value); |
| 3855 return value; | |
| 3856 } | 3922 } |
| 3857 | 3923 |
| 3858 | 3924 |
| 3859 static MaybeObject* SetPropertyToFieldWithAttributes( | 3925 void JSObject::SetPropertyToFieldWithAttributes(LookupResult* lookup, |
| 3860 LookupResult* lookup, | 3926 Handle<Name> name, |
| 3861 Handle<Name> name, | 3927 Handle<Object> value, |
| 3862 Handle<Object> value, | 3928 PropertyAttributes attributes) { |
| 3863 PropertyAttributes attributes) { | |
| 3864 if (lookup->GetAttributes() == attributes) { | 3929 if (lookup->GetAttributes() == attributes) { |
| 3865 if (value->IsUninitialized()) return *value; | 3930 if (value->IsUninitialized()) return; |
| 3866 return SetPropertyToField(lookup, name, value); | 3931 SetPropertyToField(lookup, name, value); |
| 3867 } else { | 3932 } else { |
| 3868 return ConvertAndSetLocalProperty(lookup, *name, *value, attributes); | 3933 ConvertAndSetLocalProperty(lookup, name, value, attributes); |
| 3869 } | 3934 } |
| 3870 } | 3935 } |
| 3871 | 3936 |
| 3872 | 3937 |
| 3873 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, | 3938 MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, |
| 3874 Name* name_raw, | 3939 Name* name_raw, |
| 3875 Object* value_raw, | 3940 Object* value_raw, |
| 3876 PropertyAttributes attributes, | 3941 PropertyAttributes attributes, |
| 3877 StrictModeFlag strict_mode, | 3942 StrictModeFlag strict_mode, |
| 3878 StoreFromKeyed store_mode) { | 3943 StoreFromKeyed store_mode) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3946 } | 4011 } |
| 3947 | 4012 |
| 3948 Handle<Object> old_value(heap->the_hole_value(), isolate); | 4013 Handle<Object> old_value(heap->the_hole_value(), isolate); |
| 3949 if (FLAG_harmony_observation && | 4014 if (FLAG_harmony_observation && |
| 3950 map()->is_observed() && lookup->IsDataProperty()) { | 4015 map()->is_observed() && lookup->IsDataProperty()) { |
| 3951 old_value = Object::GetProperty(self, name); | 4016 old_value = Object::GetProperty(self, name); |
| 3952 } | 4017 } |
| 3953 | 4018 |
| 3954 // This is a real property that is not read-only, or it is a | 4019 // This is a real property that is not read-only, or it is a |
| 3955 // transition or null descriptor and there are no setters in the prototypes. | 4020 // transition or null descriptor and there are no setters in the prototypes. |
| 3956 MaybeObject* result = *value; | |
| 3957 switch (lookup->type()) { | 4021 switch (lookup->type()) { |
| 3958 case NORMAL: | 4022 case NORMAL: |
| 3959 result = lookup->holder()->SetNormalizedProperty(lookup, *value); | 4023 SetNormalizedProperty(handle(lookup->holder()), lookup, value); |
| 3960 break; | 4024 break; |
| 3961 case FIELD: | 4025 case FIELD: |
| 3962 result = SetPropertyToField(lookup, name, value); | 4026 SetPropertyToField(lookup, name, value); |
| 3963 break; | 4027 break; |
| 3964 case CONSTANT: | 4028 case CONSTANT: |
| 3965 // Only replace the constant if necessary. | 4029 // Only replace the constant if necessary. |
| 3966 if (*value == lookup->GetConstant()) return *value; | 4030 if (*value != lookup->GetConstant()) { |
| 3967 result = SetPropertyToField(lookup, name, value); | 4031 SetPropertyToField(lookup, name, value); |
| 4032 } |
| 3968 break; | 4033 break; |
| 3969 case CALLBACKS: { | 4034 case CALLBACKS: { |
| 3970 Object* callback_object = lookup->GetCallbackObject(); | 4035 Object* callback_object = lookup->GetCallbackObject(); |
| 3971 return self->SetPropertyWithCallback( | 4036 return self->SetPropertyWithCallback( |
| 3972 callback_object, *name, *value, lookup->holder(), strict_mode); | 4037 callback_object, *name, *value, lookup->holder(), strict_mode); |
| 3973 } | 4038 } |
| 3974 case INTERCEPTOR: | 4039 case INTERCEPTOR: { |
| 3975 result = lookup->holder()->SetPropertyWithInterceptor( | 4040 RETURN_IF_EMPTY_HANDLE( |
| 3976 *name, *value, attributes, strict_mode); | 4041 isolate, |
| 4042 SetPropertyWithInterceptor( |
| 4043 handle(lookup->holder()), name, value, attributes, strict_mode)); |
| 3977 break; | 4044 break; |
| 4045 } |
| 3978 case TRANSITION: { | 4046 case TRANSITION: { |
| 3979 result = SetPropertyUsingTransition(lookup, name, value, attributes); | 4047 SetPropertyUsingTransition(lookup, name, value, attributes); |
| 3980 break; | 4048 break; |
| 3981 } | 4049 } |
| 3982 case HANDLER: | 4050 case HANDLER: |
| 3983 case NONEXISTENT: | 4051 case NONEXISTENT: |
| 3984 UNREACHABLE(); | 4052 UNREACHABLE(); |
| 3985 } | 4053 } |
| 3986 | 4054 |
| 3987 Handle<Object> hresult; | |
| 3988 if (!result->ToHandle(&hresult, isolate)) return result; | |
| 3989 | |
| 3990 if (FLAG_harmony_observation && self->map()->is_observed()) { | 4055 if (FLAG_harmony_observation && self->map()->is_observed()) { |
| 3991 if (lookup->IsTransition()) { | 4056 if (lookup->IsTransition()) { |
| 3992 EnqueueChangeRecord(self, "new", name, old_value); | 4057 EnqueueChangeRecord(self, "new", name, old_value); |
| 3993 } else { | 4058 } else { |
| 3994 LookupResult new_lookup(isolate); | 4059 LookupResult new_lookup(isolate); |
| 3995 self->LocalLookup(*name, &new_lookup, true); | 4060 self->LocalLookup(*name, &new_lookup, true); |
| 3996 if (new_lookup.IsDataProperty()) { | 4061 if (new_lookup.IsDataProperty()) { |
| 3997 Handle<Object> new_value = Object::GetProperty(self, name); | 4062 Handle<Object> new_value = Object::GetProperty(self, name); |
| 3998 if (!new_value->SameValue(*old_value)) { | 4063 if (!new_value->SameValue(*old_value)) { |
| 3999 EnqueueChangeRecord(self, "updated", name, old_value); | 4064 EnqueueChangeRecord(self, "updated", name, old_value); |
| 4000 } | 4065 } |
| 4001 } | 4066 } |
| 4002 } | 4067 } |
| 4003 } | 4068 } |
| 4004 | 4069 |
| 4005 return *hresult; | 4070 return *value; |
| 4006 } | 4071 } |
| 4007 | 4072 |
| 4008 | 4073 |
| 4009 // Set a real local property, even if it is READ_ONLY. If the property is not | 4074 // Set a real local property, even if it is READ_ONLY. If the property is not |
| 4010 // present, add it with attributes NONE. This code is an exact clone of | 4075 // present, add it with attributes NONE. This code is an exact clone of |
| 4011 // SetProperty, with the check for IsReadOnly and the check for a | 4076 // SetProperty, with the check for IsReadOnly and the check for a |
| 4012 // callback setter removed. The two lines looking up the LookupResult | 4077 // callback setter removed. The two lines looking up the LookupResult |
| 4013 // result are also added. If one of the functions is changed, the other | 4078 // result are also added. If one of the functions is changed, the other |
| 4014 // should be. | 4079 // should be. |
| 4015 // Note that this method cannot be used to set the prototype of a function | 4080 // Note that this method cannot be used to set the prototype of a function |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4089 | 4154 |
| 4090 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate); | 4155 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate); |
| 4091 PropertyAttributes old_attributes = ABSENT; | 4156 PropertyAttributes old_attributes = ABSENT; |
| 4092 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); | 4157 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); |
| 4093 if (is_observed && lookup.IsProperty()) { | 4158 if (is_observed && lookup.IsProperty()) { |
| 4094 if (lookup.IsDataProperty()) old_value = Object::GetProperty(self, name); | 4159 if (lookup.IsDataProperty()) old_value = Object::GetProperty(self, name); |
| 4095 old_attributes = lookup.GetAttributes(); | 4160 old_attributes = lookup.GetAttributes(); |
| 4096 } | 4161 } |
| 4097 | 4162 |
| 4098 // Check of IsReadOnly removed from here in clone. | 4163 // Check of IsReadOnly removed from here in clone. |
| 4099 MaybeObject* result = *value; | |
| 4100 switch (lookup.type()) { | 4164 switch (lookup.type()) { |
| 4101 case NORMAL: | 4165 case NORMAL: |
| 4102 result = self->ReplaceSlowProperty(*name, *value, attributes); | 4166 ReplaceSlowProperty(self, name, value, attributes); |
| 4103 break; | 4167 break; |
| 4104 case FIELD: | 4168 case FIELD: |
| 4105 result = SetPropertyToFieldWithAttributes( | 4169 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); |
| 4106 &lookup, name, value, attributes); | |
| 4107 break; | 4170 break; |
| 4108 case CONSTANT: | 4171 case CONSTANT: |
| 4109 // Only replace the constant if necessary. | 4172 // Only replace the constant if necessary. |
| 4110 if (lookup.GetAttributes() != attributes || | 4173 if (lookup.GetAttributes() != attributes || |
| 4111 *value != lookup.GetConstant()) { | 4174 *value != lookup.GetConstant()) { |
| 4112 result = SetPropertyToFieldWithAttributes( | 4175 SetPropertyToFieldWithAttributes(&lookup, name, value, attributes); |
| 4113 &lookup, name, value, attributes); | |
| 4114 } | 4176 } |
| 4115 break; | 4177 break; |
| 4116 case CALLBACKS: | 4178 case CALLBACKS: |
| 4117 result = ConvertAndSetLocalProperty(&lookup, *name, *value, attributes); | 4179 ConvertAndSetLocalProperty(&lookup, name, value, attributes); |
| 4118 break; | 4180 break; |
| 4119 case TRANSITION: | 4181 case TRANSITION: |
| 4120 result = SetPropertyUsingTransition(&lookup, name, value, attributes); | 4182 SetPropertyUsingTransition(&lookup, name, value, attributes); |
| 4121 break; | 4183 break; |
| 4122 case NONEXISTENT: | 4184 case NONEXISTENT: |
| 4123 case HANDLER: | 4185 case HANDLER: |
| 4124 case INTERCEPTOR: | 4186 case INTERCEPTOR: |
| 4125 UNREACHABLE(); | 4187 UNREACHABLE(); |
| 4126 } | 4188 } |
| 4127 | 4189 |
| 4128 Handle<Object> hresult; | |
| 4129 if (!result->ToHandle(&hresult, isolate)) return result; | |
| 4130 | |
| 4131 if (is_observed) { | 4190 if (is_observed) { |
| 4132 if (lookup.IsTransition()) { | 4191 if (lookup.IsTransition()) { |
| 4133 EnqueueChangeRecord(self, "new", name, old_value); | 4192 EnqueueChangeRecord(self, "new", name, old_value); |
| 4134 } else if (old_value->IsTheHole()) { | 4193 } else if (old_value->IsTheHole()) { |
| 4135 EnqueueChangeRecord(self, "reconfigured", name, old_value); | 4194 EnqueueChangeRecord(self, "reconfigured", name, old_value); |
| 4136 } else { | 4195 } else { |
| 4137 LookupResult new_lookup(isolate); | 4196 LookupResult new_lookup(isolate); |
| 4138 self->LocalLookup(*name, &new_lookup, true); | 4197 self->LocalLookup(*name, &new_lookup, true); |
| 4139 bool value_changed = false; | 4198 bool value_changed = false; |
| 4140 if (new_lookup.IsDataProperty()) { | 4199 if (new_lookup.IsDataProperty()) { |
| 4141 Handle<Object> new_value = Object::GetProperty(self, name); | 4200 Handle<Object> new_value = Object::GetProperty(self, name); |
| 4142 value_changed = !old_value->SameValue(*new_value); | 4201 value_changed = !old_value->SameValue(*new_value); |
| 4143 } | 4202 } |
| 4144 if (new_lookup.GetAttributes() != old_attributes) { | 4203 if (new_lookup.GetAttributes() != old_attributes) { |
| 4145 if (!value_changed) old_value = isolate->factory()->the_hole_value(); | 4204 if (!value_changed) old_value = isolate->factory()->the_hole_value(); |
| 4146 EnqueueChangeRecord(self, "reconfigured", name, old_value); | 4205 EnqueueChangeRecord(self, "reconfigured", name, old_value); |
| 4147 } else if (value_changed) { | 4206 } else if (value_changed) { |
| 4148 EnqueueChangeRecord(self, "updated", name, old_value); | 4207 EnqueueChangeRecord(self, "updated", name, old_value); |
| 4149 } | 4208 } |
| 4150 } | 4209 } |
| 4151 } | 4210 } |
| 4152 | 4211 |
| 4153 return *hresult; | 4212 return *value; |
| 4154 } | 4213 } |
| 4155 | 4214 |
| 4156 | 4215 |
| 4157 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor( | 4216 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor( |
| 4158 JSObject* receiver, | 4217 JSObject* receiver, |
| 4159 Name* name, | 4218 Name* name, |
| 4160 bool continue_search) { | 4219 bool continue_search) { |
| 4161 // Check local property, ignore interceptor. | 4220 // Check local property, ignore interceptor. |
| 4162 LookupResult result(GetIsolate()); | 4221 LookupResult result(GetIsolate()); |
| 4163 LocalLookupRealNamedProperty(name, &result); | 4222 LocalLookupRealNamedProperty(name, &result); |
| (...skipping 11821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15985 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16044 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 15986 static const char* error_messages_[] = { | 16045 static const char* error_messages_[] = { |
| 15987 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16046 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 15988 }; | 16047 }; |
| 15989 #undef ERROR_MESSAGES_TEXTS | 16048 #undef ERROR_MESSAGES_TEXTS |
| 15990 return error_messages_[reason]; | 16049 return error_messages_[reason]; |
| 15991 } | 16050 } |
| 15992 | 16051 |
| 15993 | 16052 |
| 15994 } } // namespace v8::internal | 16053 } } // namespace v8::internal |
| OLD | NEW |