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

Unified Diff: src/objects.cc

Issue 1419823008: Fix Object.preventExtensions, .seal, .freeze on typed arrays (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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/messages.h ('k') | test/mjsunit/compiler/regress-447567.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 433dda7d6f98daa1aac991c04413c4d3d4501bc8..360f98a7813b8ebfd7f8fd3bf289f5d1dd9cb379 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -6794,19 +6794,15 @@ Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object,
should_throw);
}
- // It's not possible to seal objects with external array elements
- if (object->HasFixedTypedArrayElements()) {
- isolate->Throw(*isolate->factory()->NewTypeError(
- MessageTemplate::kCannotPreventExtExternalArray));
- return Nothing<bool>();
- }
-
- // If there are fast elements we normalize.
- Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
- DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements());
+ if (!object->HasFixedTypedArrayElements()) {
+ // If there are fast elements we normalize.
+ Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
+ DCHECK(object->HasDictionaryElements() ||
+ object->HasSlowArgumentsElements());
- // Make sure that we never go back to fast case.
- object->RequireSlowElements(*dictionary);
+ // Make sure that we never go back to fast case.
+ object->RequireSlowElements(*dictionary);
+ }
// Do a map transition, other objects with this map may still
// be extensible.
@@ -6895,15 +6891,9 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
PrototypeIterator::GetCurrent<JSObject>(iter), should_throw);
}
- // It's not possible to seal or freeze objects with external array elements
- if (object->HasFixedTypedArrayElements()) {
- isolate->Throw(*isolate->factory()->NewTypeError(
- MessageTemplate::kCannotPreventExtExternalArray));
- return Nothing<bool>();
- }
-
Handle<SeededNumberDictionary> new_element_dictionary;
- if (!object->HasDictionaryElements()) {
+ if (!object->HasFixedTypedArrayElements() &&
+ !object->HasDictionaryElements()) {
int length =
object->IsJSArray()
? Smi::cast(Handle<JSArray>::cast(object)->length())->value()
@@ -6929,7 +6919,8 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
TransitionArray::SearchSpecial(*old_map, *transition_marker);
if (transition != NULL) {
Handle<Map> transition_map(transition, isolate);
- DCHECK(transition_map->has_dictionary_elements());
+ DCHECK(transition_map->has_dictionary_elements() ||
+ transition_map->has_fixed_typed_array_elements());
DCHECK(!transition_map->is_extensible());
JSObject::MigrateToMap(object, transition_map);
} else if (TransitionArray::CanHaveMoreTransitions(old_map)) {
@@ -6948,7 +6939,9 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
Handle<Map> new_map =
Map::Copy(handle(object->map()), "SlowCopyForPreventExtensions");
new_map->set_is_extensible(false);
- new_map->set_elements_kind(DICTIONARY_ELEMENTS);
+ if (!new_element_dictionary.is_null()) {
+ new_map->set_elements_kind(DICTIONARY_ELEMENTS);
+ }
JSObject::MigrateToMap(object, new_map);
if (attrs != NONE) {
@@ -6960,6 +6953,18 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
}
}
+ // Both seal and preventExtensions always go through without modifications to
+ // typed array elements. Freeze works only if there are no actual elements.
+ if (object->HasFixedTypedArrayElements()) {
+ if (attrs == FROZEN &&
+ JSArrayBufferView::cast(*object)->byte_length()->Number() > 0) {
+ isolate->Throw(*isolate->factory()->NewTypeError(
+ MessageTemplate::kCannotFreezeArrayBufferView));
+ return Nothing<bool>();
+ }
+ return Just(true);
+ }
+
DCHECK(object->map()->has_dictionary_elements());
if (!new_element_dictionary.is_null()) {
object->set_elements(*new_element_dictionary);
@@ -8520,7 +8525,9 @@ Handle<Map> Map::CopyForPreventExtensions(Handle<Map> map,
map, new_desc, new_layout_descriptor, INSERT_TRANSITION,
transition_marker, reason, SPECIAL_TRANSITION);
new_map->set_is_extensible(false);
- new_map->set_elements_kind(DICTIONARY_ELEMENTS);
+ if (!IsFixedTypedArrayElementsKind(map->elements_kind())) {
+ new_map->set_elements_kind(DICTIONARY_ELEMENTS);
+ }
return new_map;
}
« no previous file with comments | « src/messages.h ('k') | test/mjsunit/compiler/regress-447567.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698