aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/objects.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/objects.cc')
-rw-r--r--deps/v8/src/objects.cc119
1 files changed, 75 insertions, 44 deletions
diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc
index 6242198ec3..ca780dbe0e 100644
--- a/deps/v8/src/objects.cc
+++ b/deps/v8/src/objects.cc
@@ -1883,13 +1883,9 @@ void JSObject::LookupCallbackSetterInPrototypes(String* name,
pt = pt->GetPrototype()) {
JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
if (result->IsProperty()) {
- if (result->IsReadOnly()) {
- result->NotFound();
- return;
- }
- if (result->type() == CALLBACKS) {
- return;
- }
+ if (result->type() == CALLBACKS && !result->IsReadOnly()) return;
+ // Found non-callback or read-only callback, stop looking.
+ break;
}
}
result->NotFound();
@@ -2273,10 +2269,10 @@ MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler(
MaybeObject* JSObject::SetPropertyForResult(LookupResult* result,
- String* name,
- Object* value,
- PropertyAttributes attributes,
- StrictModeFlag strict_mode) {
+ String* name,
+ Object* value,
+ PropertyAttributes attributes,
+ StrictModeFlag strict_mode) {
Heap* heap = GetHeap();
// Make sure that the top context does not change when doing callbacks or
// interceptor calls.
@@ -3068,7 +3064,9 @@ MaybeObject* JSObject::DeleteDictionaryElement(uint32_t index,
Isolate* isolate = GetIsolate();
Heap* heap = isolate->heap();
FixedArray* backing_store = FixedArray::cast(elements());
- if (backing_store->map() == heap->non_strict_arguments_elements_map()) {
+ bool is_arguments =
+ (GetElementsKind() == JSObject::NON_STRICT_ARGUMENTS_ELEMENTS);
+ if (is_arguments) {
backing_store = FixedArray::cast(backing_store->get(1));
}
NumberDictionary* dictionary = NumberDictionary::cast(backing_store);
@@ -3081,7 +3079,11 @@ MaybeObject* JSObject::DeleteDictionaryElement(uint32_t index,
if (!maybe_elements->To(&new_elements)) {
return maybe_elements;
}
- set_elements(new_elements);
+ if (is_arguments) {
+ FixedArray::cast(elements())->set(1, new_elements);
+ } else {
+ set_elements(new_elements);
+ }
}
if (mode == STRICT_DELETION && result == heap->false_value()) {
// In strict mode, attempting to delete a non-configurable property
@@ -3375,23 +3377,22 @@ MaybeObject* JSObject::PreventExtensions() {
}
// If there are fast elements we normalize.
- if (HasFastElements()) {
- MaybeObject* result = NormalizeElements();
- if (result->IsFailure()) return result;
+ NumberDictionary* dictionary = NULL;
+ { MaybeObject* maybe = NormalizeElements();
+ if (!maybe->To<NumberDictionary>(&dictionary)) return maybe;
}
- // TODO(kmillikin): Handle arguments object with dictionary elements.
- ASSERT(HasDictionaryElements());
+ ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
// Make sure that we never go back to fast case.
- element_dictionary()->set_requires_slow_elements();
+ dictionary->set_requires_slow_elements();
// Do a map transition, other objects with this map may still
// be extensible.
- Object* new_map;
- { MaybeObject* maybe_new_map = map()->CopyDropTransitions();
- if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
+ Map* new_map;
+ { MaybeObject* maybe = map()->CopyDropTransitions();
+ if (!maybe->To<Map>(&new_map)) return maybe;
}
- Map::cast(new_map)->set_is_extensible(false);
- set_map(Map::cast(new_map));
+ new_map->set_is_extensible(false);
+ set_map(new_map);
ASSERT(!map()->is_extensible());
return new_map;
}
@@ -4117,6 +4118,8 @@ void Map::TraverseTransitionTree(TraverseCallback callback, void* data) {
}
}
if (!map_done) continue;
+ } else {
+ map_or_index_field = NULL;
}
// That was the regular transitions, now for the prototype transitions.
FixedArray* prototype_transitions =
@@ -9428,7 +9431,7 @@ void JSObject::GetLocalPropertyNames(FixedArray* storage, int index) {
}
ASSERT(storage->length() >= index);
} else {
- property_dictionary()->CopyKeysTo(storage);
+ property_dictionary()->CopyKeysTo(storage, StringDictionary::UNSORTED);
}
}
@@ -9505,33 +9508,49 @@ int JSObject::GetLocalElementKeys(FixedArray* storage,
break;
case DICTIONARY_ELEMENTS: {
if (storage != NULL) {
- element_dictionary()->CopyKeysTo(storage, filter);
+ element_dictionary()->CopyKeysTo(storage,
+ filter,
+ NumberDictionary::SORTED);
}
counter += element_dictionary()->NumberOfElementsFilterAttributes(filter);
break;
}
case NON_STRICT_ARGUMENTS_ELEMENTS: {
FixedArray* parameter_map = FixedArray::cast(elements());
- int length = parameter_map->length();
- for (int i = 2; i < length; ++i) {
- if (!parameter_map->get(i)->IsTheHole()) {
- if (storage != NULL) storage->set(i - 2, Smi::FromInt(i - 2));
- ++counter;
- }
- }
+ int mapped_length = parameter_map->length() - 2;
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
if (arguments->IsDictionary()) {
+ // Copy the keys from arguments first, because Dictionary::CopyKeysTo
+ // will insert in storage starting at index 0.
NumberDictionary* dictionary = NumberDictionary::cast(arguments);
- if (storage != NULL) dictionary->CopyKeysTo(storage, filter);
+ if (storage != NULL) {
+ dictionary->CopyKeysTo(storage, filter, NumberDictionary::UNSORTED);
+ }
counter += dictionary->NumberOfElementsFilterAttributes(filter);
+ for (int i = 0; i < mapped_length; ++i) {
+ if (!parameter_map->get(i + 2)->IsTheHole()) {
+ if (storage != NULL) storage->set(counter, Smi::FromInt(i));
+ ++counter;
+ }
+ }
+ if (storage != NULL) storage->SortPairs(storage, counter);
+
} else {
- int length = arguments->length();
- for (int i = 0; i < length; ++i) {
- if (!arguments->get(i)->IsTheHole()) {
- if (storage != NULL) storage->set(i, Smi::FromInt(i));
+ int backing_length = arguments->length();
+ int i = 0;
+ for (; i < mapped_length; ++i) {
+ if (!parameter_map->get(i + 2)->IsTheHole()) {
+ if (storage != NULL) storage->set(counter, Smi::FromInt(i));
+ ++counter;
+ } else if (i < backing_length && !arguments->get(i)->IsTheHole()) {
+ if (storage != NULL) storage->set(counter, Smi::FromInt(i));
++counter;
}
}
+ for (; i < backing_length; ++i) {
+ if (storage != NULL) storage->set(counter, Smi::FromInt(i));
+ ++counter;
+ }
}
break;
}
@@ -10132,7 +10151,9 @@ template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup(
Object*);
template void Dictionary<NumberDictionaryShape, uint32_t>::CopyKeysTo(
- FixedArray*, PropertyAttributes);
+ FixedArray*,
+ PropertyAttributes,
+ Dictionary<NumberDictionaryShape, uint32_t>::SortMode);
template Object* Dictionary<StringDictionaryShape, String*>::DeleteProperty(
int, JSObject::DeleteMode);
@@ -10147,7 +10168,8 @@ template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Shrink(
uint32_t);
template void Dictionary<StringDictionaryShape, String*>::CopyKeysTo(
- FixedArray*);
+ FixedArray*,
+ Dictionary<StringDictionaryShape, String*>::SortMode);
template int
Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes(
@@ -11199,8 +11221,10 @@ int Dictionary<Shape, Key>::NumberOfEnumElements() {
template<typename Shape, typename Key>
-void Dictionary<Shape, Key>::CopyKeysTo(FixedArray* storage,
- PropertyAttributes filter) {
+void Dictionary<Shape, Key>::CopyKeysTo(
+ FixedArray* storage,
+ PropertyAttributes filter,
+ typename Dictionary<Shape, Key>::SortMode sort_mode) {
ASSERT(storage->length() >= NumberOfEnumElements());
int capacity = HashTable<Shape, Key>::Capacity();
int index = 0;
@@ -11213,7 +11237,9 @@ void Dictionary<Shape, Key>::CopyKeysTo(FixedArray* storage,
if ((attr & filter) == 0) storage->set(index++, k);
}
}
- storage->SortPairs(storage, index);
+ if (sort_mode == Dictionary<Shape, Key>::SORTED) {
+ storage->SortPairs(storage, index);
+ }
ASSERT(storage->length() >= index);
}
@@ -11239,7 +11265,9 @@ void StringDictionary::CopyEnumKeysTo(FixedArray* storage,
template<typename Shape, typename Key>
-void Dictionary<Shape, Key>::CopyKeysTo(FixedArray* storage) {
+void Dictionary<Shape, Key>::CopyKeysTo(
+ FixedArray* storage,
+ typename Dictionary<Shape, Key>::SortMode sort_mode) {
ASSERT(storage->length() >= NumberOfElementsFilterAttributes(
static_cast<PropertyAttributes>(NONE)));
int capacity = HashTable<Shape, Key>::Capacity();
@@ -11252,6 +11280,9 @@ void Dictionary<Shape, Key>::CopyKeysTo(FixedArray* storage) {
storage->set(index++, k);
}
}
+ if (sort_mode == Dictionary<Shape, Key>::SORTED) {
+ storage->SortPairs(storage, index);
+ }
ASSERT(storage->length() >= index);
}