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

Side by Side Diff: src/objects.cc

Issue 1675223002: Mark maps having a hidden prototype rather than maps of hidden prototypes. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comment Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 1003 matching lines...) Expand 10 before | Expand all | Expand 10 after
1014 // TODO(dcarney): CallOptimization duplicates this logic, merge. 1014 // TODO(dcarney): CallOptimization duplicates this logic, merge.
1015 Object* FunctionTemplateInfo::GetCompatibleReceiver(Isolate* isolate, 1015 Object* FunctionTemplateInfo::GetCompatibleReceiver(Isolate* isolate,
1016 Object* receiver) { 1016 Object* receiver) {
1017 // API calls are only supported with JSObject receivers. 1017 // API calls are only supported with JSObject receivers.
1018 if (!receiver->IsJSObject()) return isolate->heap()->null_value(); 1018 if (!receiver->IsJSObject()) return isolate->heap()->null_value();
1019 Object* recv_type = this->signature(); 1019 Object* recv_type = this->signature();
1020 // No signature, return holder. 1020 // No signature, return holder.
1021 if (recv_type->IsUndefined()) return receiver; 1021 if (recv_type->IsUndefined()) return receiver;
1022 FunctionTemplateInfo* signature = FunctionTemplateInfo::cast(recv_type); 1022 FunctionTemplateInfo* signature = FunctionTemplateInfo::cast(recv_type);
1023 // Check the receiver. 1023 // Check the receiver.
1024 for (PrototypeIterator iter(isolate, receiver, 1024 for (PrototypeIterator iter(isolate, JSObject::cast(receiver),
1025 PrototypeIterator::START_AT_RECEIVER); 1025 PrototypeIterator::START_AT_RECEIVER,
1026 !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) { 1026 PrototypeIterator::END_AT_NON_HIDDEN);
1027 !iter.IsAtEnd(); iter.Advance()) {
1027 if (signature->IsTemplateFor(iter.GetCurrent())) return iter.GetCurrent(); 1028 if (signature->IsTemplateFor(iter.GetCurrent())) return iter.GetCurrent();
1028 } 1029 }
1029 return isolate->heap()->null_value(); 1030 return isolate->heap()->null_value();
1030 } 1031 }
1031 1032
1032 1033
1033 // static 1034 // static
1034 MaybeHandle<JSObject> JSObject::New(Handle<JSFunction> constructor, 1035 MaybeHandle<JSObject> JSObject::New(Handle<JSFunction> constructor,
1035 Handle<JSReceiver> new_target, 1036 Handle<JSReceiver> new_target,
1036 Handle<AllocationSite> site) { 1037 Handle<AllocationSite> site) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 } 1092 }
1092 Handle<JSReceiver> target(proxy->target(), isolate); 1093 Handle<JSReceiver> target(proxy->target(), isolate);
1093 Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate); 1094 Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
1094 1095
1095 // 5. Let trap be ? GetMethod(handler, "getPrototypeOf"). 1096 // 5. Let trap be ? GetMethod(handler, "getPrototypeOf").
1096 Handle<Object> trap; 1097 Handle<Object> trap;
1097 ASSIGN_RETURN_ON_EXCEPTION(isolate, trap, GetMethod(handler, trap_name), 1098 ASSIGN_RETURN_ON_EXCEPTION(isolate, trap, GetMethod(handler, trap_name),
1098 Object); 1099 Object);
1099 // 6. If trap is undefined, then return target.[[GetPrototypeOf]](). 1100 // 6. If trap is undefined, then return target.[[GetPrototypeOf]]().
1100 if (trap->IsUndefined()) { 1101 if (trap->IsUndefined()) {
1101 return Object::GetPrototype(isolate, target); 1102 return JSReceiver::GetPrototype(isolate, target);
1102 } 1103 }
1103 // 7. Let handlerProto be ? Call(trap, handler, «target»). 1104 // 7. Let handlerProto be ? Call(trap, handler, «target»).
1104 Handle<Object> argv[] = {target}; 1105 Handle<Object> argv[] = {target};
1105 Handle<Object> handler_proto; 1106 Handle<Object> handler_proto;
1106 ASSIGN_RETURN_ON_EXCEPTION( 1107 ASSIGN_RETURN_ON_EXCEPTION(
1107 isolate, handler_proto, 1108 isolate, handler_proto,
1108 Execution::Call(isolate, trap, handler, arraysize(argv), argv), Object); 1109 Execution::Call(isolate, trap, handler, arraysize(argv), argv), Object);
1109 // 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError. 1110 // 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError.
1110 if (!(handler_proto->IsJSReceiver() || handler_proto->IsNull())) { 1111 if (!(handler_proto->IsJSReceiver() || handler_proto->IsNull())) {
1111 THROW_NEW_ERROR(isolate, 1112 THROW_NEW_ERROR(isolate,
1112 NewTypeError(MessageTemplate::kProxyGetPrototypeOfInvalid), 1113 NewTypeError(MessageTemplate::kProxyGetPrototypeOfInvalid),
1113 Object); 1114 Object);
1114 } 1115 }
1115 // 9. Let extensibleTarget be ? IsExtensible(target). 1116 // 9. Let extensibleTarget be ? IsExtensible(target).
1116 Maybe<bool> is_extensible = JSReceiver::IsExtensible(target); 1117 Maybe<bool> is_extensible = JSReceiver::IsExtensible(target);
1117 MAYBE_RETURN_NULL(is_extensible); 1118 MAYBE_RETURN_NULL(is_extensible);
1118 // 10. If extensibleTarget is true, return handlerProto. 1119 // 10. If extensibleTarget is true, return handlerProto.
1119 if (is_extensible.FromJust()) return handler_proto; 1120 if (is_extensible.FromJust()) return handler_proto;
1120 // 11. Let targetProto be ? target.[[GetPrototypeOf]](). 1121 // 11. Let targetProto be ? target.[[GetPrototypeOf]]().
1121 Handle<Object> target_proto; 1122 Handle<Object> target_proto;
1122 ASSIGN_RETURN_ON_EXCEPTION(isolate, target_proto, 1123 ASSIGN_RETURN_ON_EXCEPTION(isolate, target_proto,
1123 Object::GetPrototype(isolate, target), Object); 1124 JSReceiver::GetPrototype(isolate, target), Object);
1124 // 12. If SameValue(handlerProto, targetProto) is false, throw a TypeError. 1125 // 12. If SameValue(handlerProto, targetProto) is false, throw a TypeError.
1125 if (!handler_proto->SameValue(*target_proto)) { 1126 if (!handler_proto->SameValue(*target_proto)) {
1126 THROW_NEW_ERROR( 1127 THROW_NEW_ERROR(
1127 isolate, 1128 isolate,
1128 NewTypeError(MessageTemplate::kProxyGetPrototypeOfNonExtensible), 1129 NewTypeError(MessageTemplate::kProxyGetPrototypeOfNonExtensible),
1129 Object); 1130 Object);
1130 } 1131 }
1131 // 13. Return handlerProto. 1132 // 13. Return handlerProto.
1132 return handler_proto; 1133 return handler_proto;
1133 } 1134 }
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1429 } else { 1430 } else {
1430 PropertyDetails original_details = property_dictionary->DetailsAt(entry); 1431 PropertyDetails original_details = property_dictionary->DetailsAt(entry);
1431 int enumeration_index = original_details.dictionary_index(); 1432 int enumeration_index = original_details.dictionary_index();
1432 DCHECK(enumeration_index > 0); 1433 DCHECK(enumeration_index > 0);
1433 details = details.set_index(enumeration_index); 1434 details = details.set_index(enumeration_index);
1434 property_dictionary->SetEntry(entry, name, value, details); 1435 property_dictionary->SetEntry(entry, name, value, details);
1435 } 1436 }
1436 } 1437 }
1437 } 1438 }
1438 1439
1439 1440 Maybe<bool> JSReceiver::HasInPrototypeChain(Isolate* isolate,
1440 Maybe<bool> Object::HasInPrototypeChain(Isolate* isolate, Handle<Object> object, 1441 Handle<JSReceiver> object,
1441 Handle<Object> proto) { 1442 Handle<Object> proto) {
1442 PrototypeIterator iter(isolate, object, PrototypeIterator::START_AT_RECEIVER); 1443 PrototypeIterator iter(isolate, object, PrototypeIterator::START_AT_RECEIVER);
1443 while (true) { 1444 while (true) {
1444 if (!iter.AdvanceFollowingProxies()) return Nothing<bool>(); 1445 if (!iter.AdvanceFollowingProxies()) return Nothing<bool>();
1445 if (iter.IsAtEnd()) return Just(false); 1446 if (iter.IsAtEnd()) return Just(false);
1446 if (iter.IsAtEnd(proto)) return Just(true); 1447 if (PrototypeIterator::GetCurrent(iter).is_identical_to(proto)) {
1448 return Just(true);
1449 }
1447 } 1450 }
1448 } 1451 }
1449 1452
1450 1453
1451 Map* Object::GetRootMap(Isolate* isolate) { 1454 Map* Object::GetRootMap(Isolate* isolate) {
1452 DisallowHeapAllocation no_alloc; 1455 DisallowHeapAllocation no_alloc;
1453 if (IsSmi()) { 1456 if (IsSmi()) {
1454 Context* native_context = isolate->context()->native_context(); 1457 Context* native_context = isolate->context()->native_context();
1455 return native_context->number_function()->initial_map(); 1458 return native_context->number_function()->initial_map();
1456 } 1459 }
(...skipping 7278 matching lines...) Expand 10 before | Expand all | Expand 10 after
8735 static Maybe<bool> GetKeys_Internal(Isolate* isolate, 8738 static Maybe<bool> GetKeys_Internal(Isolate* isolate,
8736 Handle<JSReceiver> receiver, 8739 Handle<JSReceiver> receiver,
8737 Handle<JSReceiver> object, 8740 Handle<JSReceiver> object,
8738 KeyCollectionType type, 8741 KeyCollectionType type,
8739 PropertyFilter filter, 8742 PropertyFilter filter,
8740 KeyAccumulator* accumulator) { 8743 KeyAccumulator* accumulator) {
8741 PrototypeIterator::WhereToEnd end = type == OWN_ONLY 8744 PrototypeIterator::WhereToEnd end = type == OWN_ONLY
8742 ? PrototypeIterator::END_AT_NON_HIDDEN 8745 ? PrototypeIterator::END_AT_NON_HIDDEN
8743 : PrototypeIterator::END_AT_NULL; 8746 : PrototypeIterator::END_AT_NULL;
8744 for (PrototypeIterator iter(isolate, object, 8747 for (PrototypeIterator iter(isolate, object,
8745 PrototypeIterator::START_AT_RECEIVER); 8748 PrototypeIterator::START_AT_RECEIVER, end);
8746 !iter.IsAtEnd(end); iter.Advance()) { 8749 !iter.IsAtEnd(); iter.Advance()) {
8747 Handle<JSReceiver> current = 8750 Handle<JSReceiver> current =
8748 PrototypeIterator::GetCurrent<JSReceiver>(iter); 8751 PrototypeIterator::GetCurrent<JSReceiver>(iter);
8749 Maybe<bool> result = Just(false); // Dummy initialization. 8752 Maybe<bool> result = Just(false); // Dummy initialization.
8750 if (current->IsJSProxy()) { 8753 if (current->IsJSProxy()) {
8751 if (type == OWN_ONLY) { 8754 if (type == OWN_ONLY) {
8752 result = JSProxy::OwnPropertyKeys(isolate, receiver, 8755 result = JSProxy::OwnPropertyKeys(isolate, receiver,
8753 Handle<JSProxy>::cast(current), 8756 Handle<JSProxy>::cast(current),
8754 filter, accumulator); 8757 filter, accumulator);
8755 } else { 8758 } else {
8756 DCHECK(type == INCLUDE_PROTOS); 8759 DCHECK(type == INCLUDE_PROTOS);
(...skipping 3559 matching lines...) Expand 10 before | Expand all | Expand 10 after
12316 namespace { 12319 namespace {
12317 12320
12318 bool CheckEquivalent(Map* first, Map* second) { 12321 bool CheckEquivalent(Map* first, Map* second) {
12319 return first->GetConstructor() == second->GetConstructor() && 12322 return first->GetConstructor() == second->GetConstructor() &&
12320 first->prototype() == second->prototype() && 12323 first->prototype() == second->prototype() &&
12321 first->instance_type() == second->instance_type() && 12324 first->instance_type() == second->instance_type() &&
12322 first->bit_field() == second->bit_field() && 12325 first->bit_field() == second->bit_field() &&
12323 first->is_extensible() == second->is_extensible() && 12326 first->is_extensible() == second->is_extensible() &&
12324 first->is_strong() == second->is_strong() && 12327 first->is_strong() == second->is_strong() &&
12325 first->new_target_is_base() == second->new_target_is_base() && 12328 first->new_target_is_base() == second->new_target_is_base() &&
12326 first->is_hidden_prototype() == second->is_hidden_prototype(); 12329 first->has_hidden_prototype() == second->has_hidden_prototype();
12327 } 12330 }
12328 12331
12329 } // namespace 12332 } // namespace
12330 12333
12331 12334
12332 bool Map::EquivalentToForTransition(Map* other) { 12335 bool Map::EquivalentToForTransition(Map* other) {
12333 if (!CheckEquivalent(this, other)) return false; 12336 if (!CheckEquivalent(this, other)) return false;
12334 if (instance_type() == JS_FUNCTION_TYPE) { 12337 if (instance_type() == JS_FUNCTION_TYPE) {
12335 // JSFunctions require more checks to ensure that sloppy function is 12338 // JSFunctions require more checks to ensure that sloppy function is
12336 // not equvalent to strict function. 12339 // not equvalent to strict function.
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after
12879 Handle<Cell> cell = isolate->factory()->NewCell( 12882 Handle<Cell> cell = isolate->factory()->NewCell(
12880 handle(Smi::FromInt(Map::kPrototypeChainValid), isolate)); 12883 handle(Smi::FromInt(Map::kPrototypeChainValid), isolate));
12881 proto_info->set_validity_cell(*cell); 12884 proto_info->set_validity_cell(*cell);
12882 return cell; 12885 return cell;
12883 } 12886 }
12884 12887
12885 12888
12886 // static 12889 // static
12887 void Map::SetPrototype(Handle<Map> map, Handle<Object> prototype, 12890 void Map::SetPrototype(Handle<Map> map, Handle<Object> prototype,
12888 PrototypeOptimizationMode proto_mode) { 12891 PrototypeOptimizationMode proto_mode) {
12892 bool is_hidden = false;
12889 if (prototype->IsJSObject()) { 12893 if (prototype->IsJSObject()) {
12890 Handle<JSObject> prototype_jsobj = Handle<JSObject>::cast(prototype); 12894 Handle<JSObject> prototype_jsobj = Handle<JSObject>::cast(prototype);
12891 JSObject::OptimizeAsPrototype(prototype_jsobj, proto_mode); 12895 JSObject::OptimizeAsPrototype(prototype_jsobj, proto_mode);
12896
12897 Object* maybe_constructor = prototype_jsobj->map()->GetConstructor();
12898 if (maybe_constructor->IsJSFunction()) {
12899 JSFunction* constructor = JSFunction::cast(maybe_constructor);
12900 Object* data = constructor->shared()->function_data();
12901 is_hidden = (data->IsFunctionTemplateInfo() &&
12902 FunctionTemplateInfo::cast(data)->hidden_prototype()) ||
12903 prototype->IsJSGlobalObject();
12904 }
12892 } 12905 }
12906 map->set_has_hidden_prototype(is_hidden);
12907
12893 WriteBarrierMode wb_mode = 12908 WriteBarrierMode wb_mode =
12894 prototype->IsNull() ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER; 12909 prototype->IsNull() ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
12895 map->set_prototype(*prototype, wb_mode); 12910 map->set_prototype(*prototype, wb_mode);
12896 } 12911 }
12897 12912
12898 12913
12899 Handle<Object> CacheInitialJSArrayMaps( 12914 Handle<Object> CacheInitialJSArrayMaps(
12900 Handle<Context> native_context, Handle<Map> initial_map) { 12915 Handle<Context> native_context, Handle<Map> initial_map) {
12901 // Replace all of the cached initial array maps in the native context with 12916 // Replace all of the cached initial array maps in the native context with
12902 // the appropriate transitioned elements kind maps. 12917 // the appropriate transitioned elements kind maps.
(...skipping 2741 matching lines...) Expand 10 before | Expand all | Expand 10 after
15644 // 10. If extensibleTarget is true, return booleanTrapResult. 15659 // 10. If extensibleTarget is true, return booleanTrapResult.
15645 if (is_extensible.FromJust()) { 15660 if (is_extensible.FromJust()) {
15646 if (bool_trap_result) return Just(true); 15661 if (bool_trap_result) return Just(true);
15647 RETURN_FAILURE( 15662 RETURN_FAILURE(
15648 isolate, should_throw, 15663 isolate, should_throw,
15649 NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name)); 15664 NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
15650 } 15665 }
15651 // 11. Let targetProto be ? target.[[GetPrototypeOf]](). 15666 // 11. Let targetProto be ? target.[[GetPrototypeOf]]().
15652 Handle<Object> target_proto; 15667 Handle<Object> target_proto;
15653 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, target_proto, 15668 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, target_proto,
15654 Object::GetPrototype(isolate, target), 15669 JSReceiver::GetPrototype(isolate, target),
15655 Nothing<bool>()); 15670 Nothing<bool>());
15656 // 12. If booleanTrapResult is true and SameValue(V, targetProto) is false, 15671 // 12. If booleanTrapResult is true and SameValue(V, targetProto) is false,
15657 // throw a TypeError exception. 15672 // throw a TypeError exception.
15658 if (bool_trap_result && !value->SameValue(*target_proto)) { 15673 if (bool_trap_result && !value->SameValue(*target_proto)) {
15659 isolate->Throw(*isolate->factory()->NewTypeError( 15674 isolate->Throw(*isolate->factory()->NewTypeError(
15660 MessageTemplate::kProxySetPrototypeOfNonExtensible)); 15675 MessageTemplate::kProxySetPrototypeOfNonExtensible));
15661 return Nothing<bool>(); 15676 return Nothing<bool>();
15662 } 15677 }
15663 // 13. Return booleanTrapResult. 15678 // 13. Return booleanTrapResult.
15664 if (bool_trap_result) return Just(true); 15679 if (bool_trap_result) return Just(true);
15665 RETURN_FAILURE( 15680 RETURN_FAILURE(
15666 isolate, should_throw, 15681 isolate, should_throw,
15667 NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name)); 15682 NewTypeError(MessageTemplate::kProxyTrapReturnedFalsish, trap_name));
15668 } 15683 }
15669 15684
15670 15685
15671 Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object, 15686 Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object,
15672 Handle<Object> value, bool from_javascript, 15687 Handle<Object> value, bool from_javascript,
15673 ShouldThrow should_throw) { 15688 ShouldThrow should_throw) {
15674 Isolate* isolate = object->GetIsolate(); 15689 Isolate* isolate = object->GetIsolate();
15675 15690
15676 const bool observed = from_javascript && object->map()->is_observed(); 15691 const bool observed = from_javascript && object->map()->is_observed();
15677 Handle<Object> old_value; 15692 Handle<Object> old_value;
15678 if (observed) { 15693 if (observed) {
15679 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, old_value, 15694 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, old_value,
15680 Object::GetPrototype(isolate, object), 15695 JSReceiver::GetPrototype(isolate, object),
15681 Nothing<bool>()); 15696 Nothing<bool>());
15682 } 15697 }
15683 15698
15684 Maybe<bool> result = 15699 Maybe<bool> result =
15685 SetPrototypeUnobserved(object, value, from_javascript, should_throw); 15700 SetPrototypeUnobserved(object, value, from_javascript, should_throw);
15686 MAYBE_RETURN(result, Nothing<bool>()); 15701 MAYBE_RETURN(result, Nothing<bool>());
15687 15702
15688 if (result.FromJust() && observed) { 15703 if (result.FromJust() && observed) {
15689 Handle<Object> new_value; 15704 Handle<Object> new_value;
15690 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, new_value, 15705 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, new_value,
15691 Object::GetPrototype(isolate, object), 15706 JSReceiver::GetPrototype(isolate, object),
15692 Nothing<bool>()); 15707 Nothing<bool>());
15693 if (!new_value->SameValue(*old_value)) { 15708 if (!new_value->SameValue(*old_value)) {
15694 RETURN_ON_EXCEPTION_VALUE( 15709 RETURN_ON_EXCEPTION_VALUE(
15695 isolate, JSObject::EnqueueChangeRecord( 15710 isolate, JSObject::EnqueueChangeRecord(
15696 object, "setPrototype", 15711 object, "setPrototype",
15697 isolate->factory()->proto_string(), old_value), 15712 isolate->factory()->proto_string(), old_value),
15698 Nothing<bool>()); 15713 Nothing<bool>());
15699 } 15714 }
15700 } 15715 }
15701 15716
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
15737 if (!value->IsJSReceiver() && !value->IsNull()) return Just(true); 15752 if (!value->IsJSReceiver() && !value->IsNull()) return Just(true);
15738 15753
15739 bool dictionary_elements_in_chain = 15754 bool dictionary_elements_in_chain =
15740 object->map()->DictionaryElementsInPrototypeChainOnly(); 15755 object->map()->DictionaryElementsInPrototypeChainOnly();
15741 15756
15742 bool all_extensible = object->map()->is_extensible(); 15757 bool all_extensible = object->map()->is_extensible();
15743 Handle<JSObject> real_receiver = object; 15758 Handle<JSObject> real_receiver = object;
15744 if (from_javascript) { 15759 if (from_javascript) {
15745 // Find the first object in the chain whose prototype object is not 15760 // Find the first object in the chain whose prototype object is not
15746 // hidden. 15761 // hidden.
15747 PrototypeIterator iter(isolate, real_receiver); 15762 PrototypeIterator iter(isolate, real_receiver,
15748 while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { 15763 PrototypeIterator::START_AT_PROTOTYPE,
15764 PrototypeIterator::END_AT_NON_HIDDEN);
15765 while (!iter.IsAtEnd()) {
15749 // Casting to JSObject is fine because hidden prototypes are never 15766 // Casting to JSObject is fine because hidden prototypes are never
15750 // JSProxies. 15767 // JSProxies.
15751 real_receiver = PrototypeIterator::GetCurrent<JSObject>(iter); 15768 real_receiver = PrototypeIterator::GetCurrent<JSObject>(iter);
15752 iter.Advance(); 15769 iter.Advance();
15753 all_extensible = all_extensible && real_receiver->map()->is_extensible(); 15770 all_extensible = all_extensible && real_receiver->map()->is_extensible();
15754 } 15771 }
15755 } 15772 }
15756 Handle<Map> map(real_receiver->map()); 15773 Handle<Map> map(real_receiver->map());
15757 15774
15758 // Nothing to do if prototype is already set. 15775 // Nothing to do if prototype is already set.
15759 if (map->prototype() == *value) return Just(true); 15776 if (map->prototype() == *value) return Just(true);
15760 15777
15761 // From 8.6.2 Object Internal Methods 15778 // From 8.6.2 Object Internal Methods
15762 // ... 15779 // ...
15763 // In addition, if [[Extensible]] is false the value of the [[Class]] and 15780 // In addition, if [[Extensible]] is false the value of the [[Class]] and
15764 // [[Prototype]] internal properties of the object may not be modified. 15781 // [[Prototype]] internal properties of the object may not be modified.
15765 // ... 15782 // ...
15766 // Implementation specific extensions that modify [[Class]], [[Prototype]] 15783 // Implementation specific extensions that modify [[Class]], [[Prototype]]
15767 // or [[Extensible]] must not violate the invariants defined in the preceding 15784 // or [[Extensible]] must not violate the invariants defined in the preceding
15768 // paragraph. 15785 // paragraph.
15769 if (!all_extensible) { 15786 if (!all_extensible) {
15770 RETURN_FAILURE(isolate, should_throw, 15787 RETURN_FAILURE(isolate, should_throw,
15771 NewTypeError(MessageTemplate::kNonExtensibleProto, object)); 15788 NewTypeError(MessageTemplate::kNonExtensibleProto, object));
15772 } 15789 }
15773 15790
15774 // Before we can set the prototype we need to be sure prototype cycles are 15791 // Before we can set the prototype we need to be sure prototype cycles are
15775 // prevented. It is sufficient to validate that the receiver is not in the 15792 // prevented. It is sufficient to validate that the receiver is not in the
15776 // new prototype chain. 15793 // new prototype chain.
15777 for (PrototypeIterator iter(isolate, *value, 15794 if (value->IsJSReceiver()) {
15778 PrototypeIterator::START_AT_RECEIVER); 15795 for (PrototypeIterator iter(isolate, JSReceiver::cast(*value),
15779 !iter.IsAtEnd(); iter.Advance()) { 15796 PrototypeIterator::START_AT_RECEIVER);
15780 if (iter.GetCurrent<JSReceiver>() == *object) { 15797 !iter.IsAtEnd(); iter.Advance()) {
15781 // Cycle detected. 15798 if (iter.GetCurrent<JSReceiver>() == *object) {
15782 RETURN_FAILURE(isolate, should_throw, 15799 // Cycle detected.
15783 NewTypeError(MessageTemplate::kCyclicProto)); 15800 RETURN_FAILURE(isolate, should_throw,
15801 NewTypeError(MessageTemplate::kCyclicProto));
15802 }
15784 } 15803 }
15785 } 15804 }
15786 15805
15787 // Set the new prototype of the object. 15806 // Set the new prototype of the object.
15788 15807
15789 isolate->UpdateArrayProtectorOnSetPrototype(real_receiver); 15808 isolate->UpdateArrayProtectorOnSetPrototype(real_receiver);
15790 15809
15791 PrototypeOptimizationMode mode = 15810 PrototypeOptimizationMode mode =
15792 from_javascript ? REGULAR_PROTOTYPE : FAST_PROTOTYPE; 15811 from_javascript ? REGULAR_PROTOTYPE : FAST_PROTOTYPE;
15793 Handle<Map> new_map = Map::TransitionToPrototype(map, value, mode); 15812 Handle<Map> new_map = Map::TransitionToPrototype(map, value, mode);
(...skipping 4052 matching lines...) Expand 10 before | Expand all | Expand 10 after
19846 if (cell->value() != *new_value) { 19865 if (cell->value() != *new_value) {
19847 cell->set_value(*new_value); 19866 cell->set_value(*new_value);
19848 Isolate* isolate = cell->GetIsolate(); 19867 Isolate* isolate = cell->GetIsolate();
19849 cell->dependent_code()->DeoptimizeDependentCodeGroup( 19868 cell->dependent_code()->DeoptimizeDependentCodeGroup(
19850 isolate, DependentCode::kPropertyCellChangedGroup); 19869 isolate, DependentCode::kPropertyCellChangedGroup);
19851 } 19870 }
19852 } 19871 }
19853 19872
19854 } // namespace internal 19873 } // namespace internal
19855 } // namespace v8 19874 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698