| 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;
|
| }
|
|
|
|
|