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

Side by Side Diff: src/objects.cc

Issue 1377103005: Restructuring of JSObject::preventExtensions. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 2 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') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // 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 5943 matching lines...) Expand 10 before | Expand all | Expand 10 after
5954 5954
5955 return context->extension_object()->ReferencesObject(obj); 5955 return context->extension_object()->ReferencesObject(obj);
5956 } 5956 }
5957 } 5957 }
5958 5958
5959 // No references to object. 5959 // No references to object.
5960 return false; 5960 return false;
5961 } 5961 }
5962 5962
5963 5963
5964 MaybeHandle<Object> JSObject::PreventExtensions(Handle<JSObject> object) { 5964 Maybe<bool> JSObject::PreventExtensionsInternal(Handle<JSObject> object) {
5965 if (!object->map()->is_extensible()) return object; 5965 Isolate* isolate = object->GetIsolate();
5966
5967 if (!object->map()->is_extensible()) return Just(true);
5966 5968
5967 if (!object->HasSloppyArgumentsElements() && !object->map()->is_observed()) { 5969 if (!object->HasSloppyArgumentsElements() && !object->map()->is_observed()) {
5968 return PreventExtensionsWithTransition<NONE>(object); 5970 return PreventExtensionsWithTransition<NONE>(object);
5969 } 5971 }
5970 5972
5971 Isolate* isolate = object->GetIsolate();
5972
5973 if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) { 5973 if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) {
5974 isolate->ReportFailedAccessCheck(object); 5974 isolate->ReportFailedAccessCheck(object);
5975 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 5975 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
5976 return isolate->factory()->false_value(); 5976 UNREACHABLE();
5977 return Just(false);
5977 } 5978 }
5978 5979
5979 if (object->IsJSGlobalProxy()) { 5980 if (object->IsJSGlobalProxy()) {
5980 PrototypeIterator iter(isolate, object); 5981 PrototypeIterator iter(isolate, object);
5981 if (iter.IsAtEnd()) return object; 5982 if (iter.IsAtEnd()) return Just(true);
5982 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); 5983 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
5983 return PreventExtensions(PrototypeIterator::GetCurrent<JSObject>(iter)); 5984 return PreventExtensionsInternal(
5985 PrototypeIterator::GetCurrent<JSObject>(iter));
5984 } 5986 }
5985 5987
5986 // It's not possible to seal objects with external array elements 5988 // It's not possible to seal objects with external array elements
5987 if (object->HasFixedTypedArrayElements()) { 5989 if (object->HasFixedTypedArrayElements()) {
5988 THROW_NEW_ERROR( 5990 isolate->Throw(*isolate->factory()->NewTypeError(
5989 isolate, NewTypeError(MessageTemplate::kCannotPreventExtExternalArray), 5991 MessageTemplate::kCannotPreventExtExternalArray));
5990 Object); 5992 return Nothing<bool>();
5991 } 5993 }
5992 5994
5993 // If there are fast elements we normalize. 5995 // If there are fast elements we normalize.
5994 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); 5996 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
5995 DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements()); 5997 DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements());
5996 5998
5997 // Make sure that we never go back to fast case. 5999 // Make sure that we never go back to fast case.
5998 object->RequireSlowElements(*dictionary); 6000 object->RequireSlowElements(*dictionary);
5999 6001
6000 // Do a map transition, other objects with this map may still 6002 // Do a map transition, other objects with this map may still
6001 // be extensible. 6003 // be extensible.
6002 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. 6004 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
6003 Handle<Map> new_map = Map::Copy(handle(object->map()), "PreventExtensions"); 6005 Handle<Map> new_map = Map::Copy(handle(object->map()), "PreventExtensions");
6004 6006
6005 new_map->set_is_extensible(false); 6007 new_map->set_is_extensible(false);
6006 JSObject::MigrateToMap(object, new_map); 6008 JSObject::MigrateToMap(object, new_map);
6007 DCHECK(!object->map()->is_extensible()); 6009 DCHECK(!object->map()->is_extensible());
6008 6010
6009 if (object->map()->is_observed()) { 6011 if (object->map()->is_observed()) {
6010 RETURN_ON_EXCEPTION( 6012 RETURN_ON_EXCEPTION_VALUE(
6011 isolate, 6013 isolate,
6012 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), 6014 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(),
6013 isolate->factory()->the_hole_value()), 6015 isolate->factory()->the_hole_value()),
6014 Object); 6016 Nothing<bool>());
6015 } 6017 }
6016 return object; 6018 return Just(true);
6017 } 6019 }
6018 6020
6019 6021
6022 static MaybeHandle<Object> ReturnObjectOrThrowTypeError(
6023 Handle<JSObject> object, Maybe<bool> maybe, MessageTemplate::Template msg) {
6024 if (!maybe.IsJust()) return MaybeHandle<Object>();
6025 if (maybe.FromJust()) return object;
6026 Isolate* isolate = object->GetIsolate();
6027 THROW_NEW_ERROR(isolate, NewTypeError(msg), Object);
6028 }
6029
6030
6031 MaybeHandle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
6032 return ReturnObjectOrThrowTypeError(object, PreventExtensionsInternal(object),
6033 MessageTemplate::kCannotPreventExt);
6034 }
6035
6036
6020 bool JSObject::IsExtensible(Handle<JSObject> object) { 6037 bool JSObject::IsExtensible(Handle<JSObject> object) {
6021 Isolate* isolate = object->GetIsolate(); 6038 Isolate* isolate = object->GetIsolate();
6022 if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) { 6039 if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) {
6023 return true; 6040 return true;
6024 } 6041 }
6025 if (object->IsJSGlobalProxy()) { 6042 if (object->IsJSGlobalProxy()) {
6026 PrototypeIterator iter(isolate, *object); 6043 PrototypeIterator iter(isolate, *object);
6027 if (iter.IsAtEnd()) return false; 6044 if (iter.IsAtEnd()) return false;
6028 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); 6045 DCHECK(iter.GetCurrent()->IsJSGlobalObject());
6029 return iter.GetCurrent<JSObject>()->map()->is_extensible(); 6046 return iter.GetCurrent<JSObject>()->map()->is_extensible();
(...skipping 20 matching lines...) Expand all
6050 } 6067 }
6051 details = details.CopyAddAttributes( 6068 details = details.CopyAddAttributes(
6052 static_cast<PropertyAttributes>(attrs)); 6069 static_cast<PropertyAttributes>(attrs));
6053 dictionary->DetailsAtPut(i, details); 6070 dictionary->DetailsAtPut(i, details);
6054 } 6071 }
6055 } 6072 }
6056 } 6073 }
6057 6074
6058 6075
6059 template <PropertyAttributes attrs> 6076 template <PropertyAttributes attrs>
6060 MaybeHandle<Object> JSObject::PreventExtensionsWithTransition( 6077 Maybe<bool> JSObject::PreventExtensionsWithTransition(Handle<JSObject> object) {
6061 Handle<JSObject> object) {
6062 STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN); 6078 STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN);
6063 6079
6064 // Sealing/freezing sloppy arguments should be handled elsewhere. 6080 // Sealing/freezing sloppy arguments should be handled elsewhere.
6065 DCHECK(!object->HasSloppyArgumentsElements()); 6081 DCHECK(!object->HasSloppyArgumentsElements());
6066 DCHECK(!object->map()->is_observed()); 6082 DCHECK(!object->map()->is_observed());
6067 6083
6068 Isolate* isolate = object->GetIsolate(); 6084 Isolate* isolate = object->GetIsolate();
6069 if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) { 6085 if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) {
6070 isolate->ReportFailedAccessCheck(object); 6086 isolate->ReportFailedAccessCheck(object);
6071 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 6087 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
6072 return isolate->factory()->false_value(); 6088 UNREACHABLE();
6073 } 6089 }
6074 6090
6075 if (object->IsJSGlobalProxy()) { 6091 if (object->IsJSGlobalProxy()) {
6076 PrototypeIterator iter(isolate, object); 6092 PrototypeIterator iter(isolate, object);
6077 if (iter.IsAtEnd()) return object; 6093 if (iter.IsAtEnd()) return Just(true);
6078 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); 6094 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
6079 return PreventExtensionsWithTransition<attrs>( 6095 return PreventExtensionsWithTransition<attrs>(
6080 PrototypeIterator::GetCurrent<JSObject>(iter)); 6096 PrototypeIterator::GetCurrent<JSObject>(iter));
6081 } 6097 }
6082 6098
6083 // It's not possible to seal or freeze objects with external array elements 6099 // It's not possible to seal or freeze objects with external array elements
6084 if (object->HasFixedTypedArrayElements()) { 6100 if (object->HasFixedTypedArrayElements()) {
6085 THROW_NEW_ERROR( 6101 isolate->Throw(*isolate->factory()->NewTypeError(
6086 isolate, NewTypeError(MessageTemplate::kCannotPreventExtExternalArray), 6102 MessageTemplate::kCannotPreventExtExternalArray));
6087 Object); 6103 return Nothing<bool>();
6088 } 6104 }
6089 6105
6090 Handle<SeededNumberDictionary> new_element_dictionary; 6106 Handle<SeededNumberDictionary> new_element_dictionary;
6091 if (!object->HasDictionaryElements()) { 6107 if (!object->HasDictionaryElements()) {
6092 int length = 6108 int length =
6093 object->IsJSArray() 6109 object->IsJSArray()
6094 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value() 6110 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value()
6095 : object->elements()->length(); 6111 : object->elements()->length();
6096 new_element_dictionary = 6112 new_element_dictionary =
6097 length == 0 ? isolate->factory()->empty_slow_element_dictionary() 6113 length == 0 ? isolate->factory()->empty_slow_element_dictionary()
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
6152 6168
6153 if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) { 6169 if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) {
6154 SeededNumberDictionary* dictionary = object->element_dictionary(); 6170 SeededNumberDictionary* dictionary = object->element_dictionary();
6155 // Make sure we never go back to the fast case 6171 // Make sure we never go back to the fast case
6156 object->RequireSlowElements(dictionary); 6172 object->RequireSlowElements(dictionary);
6157 if (attrs != NONE) { 6173 if (attrs != NONE) {
6158 ApplyAttributesToDictionary(dictionary, attrs); 6174 ApplyAttributesToDictionary(dictionary, attrs);
6159 } 6175 }
6160 } 6176 }
6161 6177
6162 return object; 6178 return Just(true);
6163 } 6179 }
6164 6180
6165 6181
6166 MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) { 6182 MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) {
6167 return PreventExtensionsWithTransition<FROZEN>(object); 6183 return ReturnObjectOrThrowTypeError(
6184 object, PreventExtensionsWithTransition<FROZEN>(object),
6185 MessageTemplate::kCannotPreventExt);
6168 } 6186 }
6169 6187
6170 6188
6171 MaybeHandle<Object> JSObject::Seal(Handle<JSObject> object) { 6189 MaybeHandle<Object> JSObject::Seal(Handle<JSObject> object) {
6172 return PreventExtensionsWithTransition<SEALED>(object); 6190 return ReturnObjectOrThrowTypeError(
6191 object, PreventExtensionsWithTransition<SEALED>(object),
6192 MessageTemplate::kCannotPreventExt);
6173 } 6193 }
6174 6194
6175 6195
6176 void JSObject::SetObserved(Handle<JSObject> object) { 6196 void JSObject::SetObserved(Handle<JSObject> object) {
6177 DCHECK(!object->IsJSGlobalProxy()); 6197 DCHECK(!object->IsJSGlobalProxy());
6178 DCHECK(!object->IsJSGlobalObject()); 6198 DCHECK(!object->IsJSGlobalObject());
6179 Isolate* isolate = object->GetIsolate(); 6199 Isolate* isolate = object->GetIsolate();
6180 Handle<Map> new_map; 6200 Handle<Map> new_map;
6181 Handle<Map> old_map(object->map(), isolate); 6201 Handle<Map> old_map(object->map(), isolate);
6182 DCHECK(!old_map->is_observed()); 6202 DCHECK(!old_map->is_observed());
(...skipping 10685 matching lines...) Expand 10 before | Expand all | Expand 10 after
16868 if (cell->value() != *new_value) { 16888 if (cell->value() != *new_value) {
16869 cell->set_value(*new_value); 16889 cell->set_value(*new_value);
16870 Isolate* isolate = cell->GetIsolate(); 16890 Isolate* isolate = cell->GetIsolate();
16871 cell->dependent_code()->DeoptimizeDependentCodeGroup( 16891 cell->dependent_code()->DeoptimizeDependentCodeGroup(
16872 isolate, DependentCode::kPropertyCellChangedGroup); 16892 isolate, DependentCode::kPropertyCellChangedGroup);
16873 } 16893 }
16874 } 16894 }
16875 16895
16876 } // namespace internal 16896 } // namespace internal
16877 } // namespace v8 16897 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698