OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/objects.h" | 5 #include "src/objects.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <iomanip> | 8 #include <iomanip> |
9 #include <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 4811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4822 return handle(native_context->slow_aliased_arguments_map()); | 4822 return handle(native_context->slow_aliased_arguments_map()); |
4823 } | 4823 } |
4824 } else if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) { | 4824 } else if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) { |
4825 if (*map == native_context->slow_aliased_arguments_map()) { | 4825 if (*map == native_context->slow_aliased_arguments_map()) { |
4826 DCHECK_EQ(FAST_SLOPPY_ARGUMENTS_ELEMENTS, to_kind); | 4826 DCHECK_EQ(FAST_SLOPPY_ARGUMENTS_ELEMENTS, to_kind); |
4827 return handle(native_context->fast_aliased_arguments_map()); | 4827 return handle(native_context->fast_aliased_arguments_map()); |
4828 } | 4828 } |
4829 } else if (IsFastElementsKind(from_kind) && IsFastElementsKind(to_kind)) { | 4829 } else if (IsFastElementsKind(from_kind) && IsFastElementsKind(to_kind)) { |
4830 // Reuse map transitions for JSArrays. | 4830 // Reuse map transitions for JSArrays. |
4831 DisallowHeapAllocation no_gc; | 4831 DisallowHeapAllocation no_gc; |
4832 Strength strength = map->is_strong() ? Strength::STRONG : Strength::WEAK; | 4832 if (native_context->get(Context::ArrayMapIndex(from_kind)) == *map) { |
4833 if (native_context->get(Context::ArrayMapIndex(from_kind, strength)) == | |
4834 *map) { | |
4835 Object* maybe_transitioned_map = | 4833 Object* maybe_transitioned_map = |
4836 native_context->get(Context::ArrayMapIndex(to_kind, strength)); | 4834 native_context->get(Context::ArrayMapIndex(to_kind)); |
4837 if (maybe_transitioned_map->IsMap()) { | 4835 if (maybe_transitioned_map->IsMap()) { |
4838 return handle(Map::cast(maybe_transitioned_map), isolate); | 4836 return handle(Map::cast(maybe_transitioned_map), isolate); |
4839 } | 4837 } |
4840 } | 4838 } |
4841 } | 4839 } |
4842 | 4840 |
4843 DCHECK(!map->IsUndefined()); | 4841 DCHECK(!map->IsUndefined()); |
4844 // Check if we can go back in the elements kind transition chain. | 4842 // Check if we can go back in the elements kind transition chain. |
4845 if (IsHoleyElementsKind(from_kind) && | 4843 if (IsHoleyElementsKind(from_kind) && |
4846 to_kind == GetPackedElementsKind(from_kind) && | 4844 to_kind == GetPackedElementsKind(from_kind) && |
(...skipping 1349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6196 break; | 6194 break; |
6197 } | 6195 } |
6198 case LookupIterator::INTEGER_INDEXED_EXOTIC: | 6196 case LookupIterator::INTEGER_INDEXED_EXOTIC: |
6199 return Just(true); | 6197 return Just(true); |
6200 case LookupIterator::DATA: | 6198 case LookupIterator::DATA: |
6201 if (is_observed) { | 6199 if (is_observed) { |
6202 old_value = it->GetDataValue(); | 6200 old_value = it->GetDataValue(); |
6203 } | 6201 } |
6204 // Fall through. | 6202 // Fall through. |
6205 case LookupIterator::ACCESSOR: { | 6203 case LookupIterator::ACCESSOR: { |
6206 if (!it->IsConfigurable() || receiver->map()->is_strong()) { | 6204 if (!it->IsConfigurable()) { |
6207 // Fail if the property is not configurable, or on a strong object. | 6205 // Fail if the property is not configurable. |
6208 if (is_strict(language_mode)) { | 6206 if (is_strict(language_mode)) { |
6209 MessageTemplate::Template templ = | |
6210 receiver->map()->is_strong() | |
6211 ? MessageTemplate::kStrongDeleteProperty | |
6212 : MessageTemplate::kStrictDeleteProperty; | |
6213 isolate->Throw(*isolate->factory()->NewTypeError( | 6207 isolate->Throw(*isolate->factory()->NewTypeError( |
6214 templ, it->GetName(), receiver)); | 6208 MessageTemplate::kStrictDeleteProperty, it->GetName(), |
| 6209 receiver)); |
6215 return Nothing<bool>(); | 6210 return Nothing<bool>(); |
6216 } | 6211 } |
6217 return Just(false); | 6212 return Just(false); |
6218 } | 6213 } |
6219 | 6214 |
6220 it->Delete(); | 6215 it->Delete(); |
6221 | 6216 |
6222 if (is_observed) { | 6217 if (is_observed) { |
6223 RETURN_ON_EXCEPTION_VALUE( | 6218 RETURN_ON_EXCEPTION_VALUE( |
6224 isolate, JSObject::EnqueueChangeRecord(receiver, "delete", | 6219 isolate, JSObject::EnqueueChangeRecord(receiver, "delete", |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6624 // attributes and set the rest of the property’s attributes to their | 6619 // attributes and set the rest of the property’s attributes to their |
6625 // default values. | 6620 // default values. |
6626 // --> Folded into step 10. | 6621 // --> Folded into step 10. |
6627 } | 6622 } |
6628 | 6623 |
6629 // 8. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both | 6624 // 8. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both |
6630 // true, then: | 6625 // true, then: |
6631 } else if (current_is_data_descriptor && desc_is_data_descriptor) { | 6626 } else if (current_is_data_descriptor && desc_is_data_descriptor) { |
6632 // 8a. If the [[Configurable]] field of current is false, then: | 6627 // 8a. If the [[Configurable]] field of current is false, then: |
6633 if (!current->configurable()) { | 6628 if (!current->configurable()) { |
6634 // [Strong mode] Disallow changing writable -> readonly for | |
6635 // non-configurable properties. | |
6636 if (it != NULL && current->writable() && desc->has_writable() && | |
6637 !desc->writable() && object->map()->is_strong()) { | |
6638 RETURN_FAILURE(isolate, should_throw, | |
6639 NewTypeError(MessageTemplate::kStrongRedefineDisallowed, | |
6640 object, it->GetName())); | |
6641 } | |
6642 // 8a i. Return false, if the [[Writable]] field of current is false and | 6629 // 8a i. Return false, if the [[Writable]] field of current is false and |
6643 // the [[Writable]] field of Desc is true. | 6630 // the [[Writable]] field of Desc is true. |
6644 if (!current->writable() && desc->has_writable() && desc->writable()) { | 6631 if (!current->writable() && desc->has_writable() && desc->writable()) { |
6645 RETURN_FAILURE( | 6632 RETURN_FAILURE( |
6646 isolate, should_throw, | 6633 isolate, should_throw, |
6647 NewTypeError(MessageTemplate::kRedefineDisallowed, | 6634 NewTypeError(MessageTemplate::kRedefineDisallowed, |
6648 it != NULL ? it->GetName() : property_name)); | 6635 it != NULL ? it->GetName() : property_name)); |
6649 } | 6636 } |
6650 // 8a ii. If the [[Writable]] field of current is false, then: | 6637 // 8a ii. If the [[Writable]] field of current is false, then: |
6651 if (!current->writable()) { | 6638 if (!current->writable()) { |
(...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7475 | 7462 |
7476 | 7463 |
7477 Maybe<bool> JSReceiver::SetIntegrityLevel(Handle<JSReceiver> receiver, | 7464 Maybe<bool> JSReceiver::SetIntegrityLevel(Handle<JSReceiver> receiver, |
7478 IntegrityLevel level, | 7465 IntegrityLevel level, |
7479 ShouldThrow should_throw) { | 7466 ShouldThrow should_throw) { |
7480 DCHECK(level == SEALED || level == FROZEN); | 7467 DCHECK(level == SEALED || level == FROZEN); |
7481 | 7468 |
7482 if (receiver->IsJSObject()) { | 7469 if (receiver->IsJSObject()) { |
7483 Handle<JSObject> object = Handle<JSObject>::cast(receiver); | 7470 Handle<JSObject> object = Handle<JSObject>::cast(receiver); |
7484 if (!object->HasSloppyArgumentsElements() && | 7471 if (!object->HasSloppyArgumentsElements() && |
7485 !object->map()->is_observed() && | 7472 !object->map()->is_observed()) { // Fast path. |
7486 (!object->map()->is_strong() || level == SEALED)) { // Fast path. | |
7487 if (level == SEALED) { | 7473 if (level == SEALED) { |
7488 return JSObject::PreventExtensionsWithTransition<SEALED>(object, | 7474 return JSObject::PreventExtensionsWithTransition<SEALED>(object, |
7489 should_throw); | 7475 should_throw); |
7490 } else { | 7476 } else { |
7491 return JSObject::PreventExtensionsWithTransition<FROZEN>(object, | 7477 return JSObject::PreventExtensionsWithTransition<FROZEN>(object, |
7492 should_throw); | 7478 should_throw); |
7493 } | 7479 } |
7494 } | 7480 } |
7495 } | 7481 } |
7496 | 7482 |
(...skipping 1754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9251 | 9237 |
9252 return result; | 9238 return result; |
9253 } | 9239 } |
9254 | 9240 |
9255 | 9241 |
9256 Handle<Map> Map::CopyInitialMap(Handle<Map> map, int instance_size, | 9242 Handle<Map> Map::CopyInitialMap(Handle<Map> map, int instance_size, |
9257 int in_object_properties, | 9243 int in_object_properties, |
9258 int unused_property_fields) { | 9244 int unused_property_fields) { |
9259 #ifdef DEBUG | 9245 #ifdef DEBUG |
9260 Isolate* isolate = map->GetIsolate(); | 9246 Isolate* isolate = map->GetIsolate(); |
9261 // Strict and strong function maps have Function as a constructor but the | 9247 // Strict function maps have Function as a constructor but the |
9262 // Function's initial map is a sloppy function map. Same holds for | 9248 // Function's initial map is a sloppy function map. Same holds for |
9263 // GeneratorFunction and its initial map. | 9249 // GeneratorFunction and its initial map. |
9264 Object* constructor = map->GetConstructor(); | 9250 Object* constructor = map->GetConstructor(); |
9265 DCHECK(constructor->IsJSFunction()); | 9251 DCHECK(constructor->IsJSFunction()); |
9266 DCHECK(*map == JSFunction::cast(constructor)->initial_map() || | 9252 DCHECK(*map == JSFunction::cast(constructor)->initial_map() || |
9267 *map == *isolate->strict_function_map() || | 9253 *map == *isolate->strict_function_map() || |
9268 *map == *isolate->strong_function_map() || | 9254 *map == *isolate->strict_generator_function_map()); |
9269 *map == *isolate->strict_generator_function_map() || | |
9270 *map == *isolate->strong_generator_function_map()); | |
9271 #endif | 9255 #endif |
9272 // Initial maps must always own their descriptors and it's descriptor array | 9256 // Initial maps must always own their descriptors and it's descriptor array |
9273 // does not contain descriptors that do not belong to the map. | 9257 // does not contain descriptors that do not belong to the map. |
9274 DCHECK(map->owns_descriptors()); | 9258 DCHECK(map->owns_descriptors()); |
9275 DCHECK_EQ(map->NumberOfOwnDescriptors(), | 9259 DCHECK_EQ(map->NumberOfOwnDescriptors(), |
9276 map->instance_descriptors()->number_of_descriptors()); | 9260 map->instance_descriptors()->number_of_descriptors()); |
9277 | 9261 |
9278 Handle<Map> result = RawCopy(map, instance_size); | 9262 Handle<Map> result = RawCopy(map, instance_size); |
9279 | 9263 |
9280 // Please note instance_type and instance_size are set when allocated. | 9264 // Please note instance_type and instance_size are set when allocated. |
(...skipping 2968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12249 | 12233 |
12250 | 12234 |
12251 namespace { | 12235 namespace { |
12252 | 12236 |
12253 bool CheckEquivalent(Map* first, Map* second) { | 12237 bool CheckEquivalent(Map* first, Map* second) { |
12254 return first->GetConstructor() == second->GetConstructor() && | 12238 return first->GetConstructor() == second->GetConstructor() && |
12255 first->prototype() == second->prototype() && | 12239 first->prototype() == second->prototype() && |
12256 first->instance_type() == second->instance_type() && | 12240 first->instance_type() == second->instance_type() && |
12257 first->bit_field() == second->bit_field() && | 12241 first->bit_field() == second->bit_field() && |
12258 first->is_extensible() == second->is_extensible() && | 12242 first->is_extensible() == second->is_extensible() && |
12259 first->is_strong() == second->is_strong() && | |
12260 first->new_target_is_base() == second->new_target_is_base() && | 12243 first->new_target_is_base() == second->new_target_is_base() && |
12261 first->has_hidden_prototype() == second->has_hidden_prototype(); | 12244 first->has_hidden_prototype() == second->has_hidden_prototype(); |
12262 } | 12245 } |
12263 | 12246 |
12264 } // namespace | 12247 } // namespace |
12265 | 12248 |
12266 | 12249 |
12267 bool Map::EquivalentToForTransition(Map* other) { | 12250 bool Map::EquivalentToForTransition(Map* other) { |
12268 if (!CheckEquivalent(this, other)) return false; | 12251 if (!CheckEquivalent(this, other)) return false; |
12269 if (instance_type() == JS_FUNCTION_TYPE) { | 12252 if (instance_type() == JS_FUNCTION_TYPE) { |
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12839 WriteBarrierMode wb_mode = | 12822 WriteBarrierMode wb_mode = |
12840 prototype->IsNull() ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER; | 12823 prototype->IsNull() ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER; |
12841 map->set_prototype(*prototype, wb_mode); | 12824 map->set_prototype(*prototype, wb_mode); |
12842 } | 12825 } |
12843 | 12826 |
12844 | 12827 |
12845 Handle<Object> CacheInitialJSArrayMaps( | 12828 Handle<Object> CacheInitialJSArrayMaps( |
12846 Handle<Context> native_context, Handle<Map> initial_map) { | 12829 Handle<Context> native_context, Handle<Map> initial_map) { |
12847 // Replace all of the cached initial array maps in the native context with | 12830 // Replace all of the cached initial array maps in the native context with |
12848 // the appropriate transitioned elements kind maps. | 12831 // the appropriate transitioned elements kind maps. |
12849 Strength strength = | |
12850 initial_map->is_strong() ? Strength::STRONG : Strength::WEAK; | |
12851 Handle<Map> current_map = initial_map; | 12832 Handle<Map> current_map = initial_map; |
12852 ElementsKind kind = current_map->elements_kind(); | 12833 ElementsKind kind = current_map->elements_kind(); |
12853 DCHECK_EQ(GetInitialFastElementsKind(), kind); | 12834 DCHECK_EQ(GetInitialFastElementsKind(), kind); |
12854 native_context->set(Context::ArrayMapIndex(kind, strength), *current_map); | 12835 native_context->set(Context::ArrayMapIndex(kind), *current_map); |
12855 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1; | 12836 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1; |
12856 i < kFastElementsKindCount; ++i) { | 12837 i < kFastElementsKindCount; ++i) { |
12857 Handle<Map> new_map; | 12838 Handle<Map> new_map; |
12858 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i); | 12839 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i); |
12859 if (Map* maybe_elements_transition = current_map->ElementsTransitionMap()) { | 12840 if (Map* maybe_elements_transition = current_map->ElementsTransitionMap()) { |
12860 new_map = handle(maybe_elements_transition); | 12841 new_map = handle(maybe_elements_transition); |
12861 } else { | 12842 } else { |
12862 new_map = Map::CopyAsElementsKind( | 12843 new_map = Map::CopyAsElementsKind( |
12863 current_map, next_kind, INSERT_TRANSITION); | 12844 current_map, next_kind, INSERT_TRANSITION); |
12864 } | 12845 } |
12865 DCHECK_EQ(next_kind, new_map->elements_kind()); | 12846 DCHECK_EQ(next_kind, new_map->elements_kind()); |
12866 native_context->set(Context::ArrayMapIndex(next_kind, strength), *new_map); | 12847 native_context->set(Context::ArrayMapIndex(next_kind), *new_map); |
12867 current_map = new_map; | 12848 current_map = new_map; |
12868 } | 12849 } |
12869 return initial_map; | 12850 return initial_map; |
12870 } | 12851 } |
12871 | 12852 |
12872 | 12853 |
12873 void JSFunction::SetInstancePrototype(Handle<JSFunction> function, | 12854 void JSFunction::SetInstancePrototype(Handle<JSFunction> function, |
12874 Handle<Object> value) { | 12855 Handle<Object> value) { |
12875 Isolate* isolate = function->GetIsolate(); | 12856 Isolate* isolate = function->GetIsolate(); |
12876 | 12857 |
(...skipping 11 matching lines...) Expand all Loading... |
12888 Handle<Map> initial_map(function->initial_map(), isolate); | 12869 Handle<Map> initial_map(function->initial_map(), isolate); |
12889 | 12870 |
12890 if (!initial_map->GetIsolate()->bootstrapper()->IsActive() && | 12871 if (!initial_map->GetIsolate()->bootstrapper()->IsActive() && |
12891 initial_map->instance_type() == JS_OBJECT_TYPE) { | 12872 initial_map->instance_type() == JS_OBJECT_TYPE) { |
12892 // Put the value in the initial map field until an initial map is needed. | 12873 // Put the value in the initial map field until an initial map is needed. |
12893 // At that point, a new initial map is created and the prototype is put | 12874 // At that point, a new initial map is created and the prototype is put |
12894 // into the initial map where it belongs. | 12875 // into the initial map where it belongs. |
12895 function->set_prototype_or_initial_map(*value); | 12876 function->set_prototype_or_initial_map(*value); |
12896 } else { | 12877 } else { |
12897 Handle<Map> new_map = Map::Copy(initial_map, "SetInstancePrototype"); | 12878 Handle<Map> new_map = Map::Copy(initial_map, "SetInstancePrototype"); |
12898 if (function->map()->is_strong()) { | |
12899 new_map->set_is_strong(); | |
12900 } | |
12901 JSFunction::SetInitialMap(function, new_map, value); | 12879 JSFunction::SetInitialMap(function, new_map, value); |
12902 | 12880 |
12903 // If the function is used as the global Array function, cache the | 12881 // If the function is used as the global Array function, cache the |
12904 // updated initial maps (and transitioned versions) in the native context. | 12882 // updated initial maps (and transitioned versions) in the native context. |
12905 Handle<Context> native_context(function->context()->native_context(), | 12883 Handle<Context> native_context(function->context()->native_context(), |
12906 isolate); | 12884 isolate); |
12907 Handle<Object> array_function( | 12885 Handle<Object> array_function( |
12908 native_context->get(Context::ARRAY_FUNCTION_INDEX), isolate); | 12886 native_context->get(Context::ARRAY_FUNCTION_INDEX), isolate); |
12909 if (array_function->IsJSFunction() && | 12887 if (array_function->IsJSFunction() && |
12910 *function == JSFunction::cast(*array_function)) { | 12888 *function == JSFunction::cast(*array_function)) { |
12911 CacheInitialJSArrayMaps(native_context, new_map); | 12889 CacheInitialJSArrayMaps(native_context, new_map); |
12912 Handle<Map> new_strong_map = Map::Copy(new_map, "SetInstancePrototype"); | |
12913 new_strong_map->set_is_strong(); | |
12914 CacheInitialJSArrayMaps(native_context, new_strong_map); | |
12915 } | 12890 } |
12916 } | 12891 } |
12917 | 12892 |
12918 // Deoptimize all code that embeds the previous initial map. | 12893 // Deoptimize all code that embeds the previous initial map. |
12919 initial_map->dependent_code()->DeoptimizeDependentCodeGroup( | 12894 initial_map->dependent_code()->DeoptimizeDependentCodeGroup( |
12920 isolate, DependentCode::kInitialMapChangedGroup); | 12895 isolate, DependentCode::kInitialMapChangedGroup); |
12921 } else { | 12896 } else { |
12922 // Put the value in the initial map field until an initial map is | 12897 // Put the value in the initial map field until an initial map is |
12923 // needed. At that point, a new initial map is created and the | 12898 // needed. At that point, a new initial map is created and the |
12924 // prototype is put into the initial map where it belongs. | 12899 // prototype is put into the initial map where it belongs. |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13089 instance_type = JS_GENERATOR_OBJECT_TYPE; | 13064 instance_type = JS_GENERATOR_OBJECT_TYPE; |
13090 } else { | 13065 } else { |
13091 instance_type = JS_OBJECT_TYPE; | 13066 instance_type = JS_OBJECT_TYPE; |
13092 } | 13067 } |
13093 int instance_size; | 13068 int instance_size; |
13094 int in_object_properties; | 13069 int in_object_properties; |
13095 function->CalculateInstanceSize(instance_type, 0, &instance_size, | 13070 function->CalculateInstanceSize(instance_type, 0, &instance_size, |
13096 &in_object_properties); | 13071 &in_object_properties); |
13097 | 13072 |
13098 Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size); | 13073 Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size); |
13099 if (function->map()->is_strong()) { | |
13100 map->set_is_strong(); | |
13101 } | |
13102 | 13074 |
13103 // Fetch or allocate prototype. | 13075 // Fetch or allocate prototype. |
13104 Handle<Object> prototype; | 13076 Handle<Object> prototype; |
13105 if (function->has_instance_prototype()) { | 13077 if (function->has_instance_prototype()) { |
13106 prototype = handle(function->instance_prototype(), isolate); | 13078 prototype = handle(function->instance_prototype(), isolate); |
13107 } else { | 13079 } else { |
13108 prototype = isolate->factory()->NewFunctionPrototype(function); | 13080 prototype = isolate->factory()->NewFunctionPrototype(function); |
13109 } | 13081 } |
13110 map->SetInObjectProperties(in_object_properties); | 13082 map->SetInObjectProperties(in_object_properties); |
13111 map->set_unused_property_fields(in_object_properties); | 13083 map->set_unused_property_fields(in_object_properties); |
(...skipping 2600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15712 !isolate->MayAccess(handle(isolate->context()), object)) { | 15684 !isolate->MayAccess(handle(isolate->context()), object)) { |
15713 isolate->ReportFailedAccessCheck(object); | 15685 isolate->ReportFailedAccessCheck(object); |
15714 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); | 15686 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); |
15715 RETURN_FAILURE(isolate, should_throw, | 15687 RETURN_FAILURE(isolate, should_throw, |
15716 NewTypeError(MessageTemplate::kNoAccess)); | 15688 NewTypeError(MessageTemplate::kNoAccess)); |
15717 } | 15689 } |
15718 } else { | 15690 } else { |
15719 DCHECK(!object->IsAccessCheckNeeded()); | 15691 DCHECK(!object->IsAccessCheckNeeded()); |
15720 } | 15692 } |
15721 | 15693 |
15722 // Strong objects may not have their prototype set via __proto__ or | |
15723 // setPrototypeOf. | |
15724 if (from_javascript && object->map()->is_strong()) { | |
15725 RETURN_FAILURE(isolate, should_throw, | |
15726 NewTypeError(MessageTemplate::kStrongSetProto, object)); | |
15727 } | |
15728 Heap* heap = isolate->heap(); | 15694 Heap* heap = isolate->heap(); |
15729 // Silently ignore the change if value is not a JSObject or null. | 15695 // Silently ignore the change if value is not a JSObject or null. |
15730 // SpiderMonkey behaves this way. | 15696 // SpiderMonkey behaves this way. |
15731 if (!value->IsJSReceiver() && !value->IsNull()) return Just(true); | 15697 if (!value->IsJSReceiver() && !value->IsNull()) return Just(true); |
15732 | 15698 |
15733 bool dictionary_elements_in_chain = | 15699 bool dictionary_elements_in_chain = |
15734 object->map()->DictionaryElementsInPrototypeChainOnly(); | 15700 object->map()->DictionaryElementsInPrototypeChainOnly(); |
15735 | 15701 |
15736 bool all_extensible = object->map()->is_extensible(); | 15702 bool all_extensible = object->map()->is_extensible(); |
15737 Handle<JSObject> real_receiver = object; | 15703 Handle<JSObject> real_receiver = object; |
(...skipping 4120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19858 if (cell->value() != *new_value) { | 19824 if (cell->value() != *new_value) { |
19859 cell->set_value(*new_value); | 19825 cell->set_value(*new_value); |
19860 Isolate* isolate = cell->GetIsolate(); | 19826 Isolate* isolate = cell->GetIsolate(); |
19861 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19827 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
19862 isolate, DependentCode::kPropertyCellChangedGroup); | 19828 isolate, DependentCode::kPropertyCellChangedGroup); |
19863 } | 19829 } |
19864 } | 19830 } |
19865 | 19831 |
19866 } // namespace internal | 19832 } // namespace internal |
19867 } // namespace v8 | 19833 } // namespace v8 |
OLD | NEW |