Index: src/elements.cc |
diff --git a/src/elements.cc b/src/elements.cc |
index d204cc52c6e67994038f9753b458c0022d2c0086..bad3c5ba8b12c535d3d061c67df11cd1832fba13 100644 |
--- a/src/elements.cc |
+++ b/src/elements.cc |
@@ -585,8 +585,8 @@ class ElementsAccessorBase : public ElementsAccessor { |
static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, |
Handle<FixedArrayBase> backing_store) { |
- return ElementsAccessorSubclass::GetAttributesImpl(holder, key, |
- backing_store) != ABSENT; |
+ return ElementsAccessorSubclass::GetAttributesImpl( |
+ *holder, key, *backing_store) != ABSENT; |
} |
virtual bool HasElement(Handle<JSObject> holder, uint32_t key, |
@@ -594,9 +594,8 @@ class ElementsAccessorBase : public ElementsAccessor { |
return ElementsAccessorSubclass::HasElementImpl(holder, key, backing_store); |
} |
- MUST_USE_RESULT virtual MaybeHandle<Object> Get( |
- Handle<Object> receiver, Handle<JSObject> holder, uint32_t key, |
- Handle<FixedArrayBase> backing_store) final { |
+ virtual Handle<Object> Get(Handle<JSObject> holder, uint32_t key, |
+ Handle<FixedArrayBase> backing_store) final { |
if (!IsExternalArrayElementsKind(ElementsTraits::Kind) && |
FLAG_trace_js_array_abuse) { |
CheckArrayAbuse(holder, "elements read", key); |
@@ -607,15 +606,11 @@ class ElementsAccessorBase : public ElementsAccessor { |
CheckArrayAbuse(holder, "external elements read", key); |
} |
- return ElementsAccessorSubclass::GetImpl( |
- receiver, holder, key, backing_store); |
+ return ElementsAccessorSubclass::GetImpl(holder, key, backing_store); |
} |
- MUST_USE_RESULT static MaybeHandle<Object> GetImpl( |
- Handle<Object> receiver, |
- Handle<JSObject> obj, |
- uint32_t key, |
- Handle<FixedArrayBase> backing_store) { |
+ static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, |
+ Handle<FixedArrayBase> backing_store) { |
if (key < ElementsAccessorSubclass::GetCapacityImpl(*obj, *backing_store)) { |
return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); |
} else { |
@@ -623,36 +618,29 @@ class ElementsAccessorBase : public ElementsAccessor { |
} |
} |
- MUST_USE_RESULT virtual PropertyAttributes GetAttributes( |
- Handle<JSObject> holder, uint32_t key, |
- Handle<FixedArrayBase> backing_store) final { |
+ virtual PropertyAttributes GetAttributes( |
+ JSObject* holder, uint32_t key, FixedArrayBase* backing_store) final { |
return ElementsAccessorSubclass::GetAttributesImpl(holder, key, |
backing_store); |
} |
- MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
- Handle<JSObject> obj, |
- uint32_t key, |
- Handle<FixedArrayBase> backing_store) { |
- if (key >= |
- ElementsAccessorSubclass::GetCapacityImpl(*obj, *backing_store)) { |
+ static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key, |
+ FixedArrayBase* backing_store) { |
+ if (key >= ElementsAccessorSubclass::GetCapacityImpl(obj, backing_store)) { |
return ABSENT; |
} |
- return |
- Handle<BackingStore>::cast(backing_store)->is_the_hole(key) |
- ? ABSENT : NONE; |
+ return BackingStore::cast(backing_store)->is_the_hole(key) ? ABSENT : NONE; |
} |
- MUST_USE_RESULT virtual MaybeHandle<AccessorPair> GetAccessorPair( |
+ virtual MaybeHandle<AccessorPair> GetAccessorPair( |
Handle<JSObject> holder, uint32_t key, |
Handle<FixedArrayBase> backing_store) final { |
return ElementsAccessorSubclass::GetAccessorPairImpl(holder, key, |
backing_store); |
} |
- MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
- Handle<JSObject> obj, |
- uint32_t key, |
+ static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
+ Handle<JSObject> obj, uint32_t key, |
Handle<FixedArrayBase> backing_store) { |
return MaybeHandle<AccessorPair>(); |
} |
@@ -734,7 +722,7 @@ class ElementsAccessorBase : public ElementsAccessor { |
from, from_start, *to, from_kind, to_start, packed_size, copy_size); |
} |
- virtual MaybeHandle<FixedArray> AddElementsToFixedArray( |
+ virtual Handle<FixedArray> AddElementsToFixedArray( |
Handle<JSObject> receiver, Handle<FixedArray> to, |
FixedArray::KeyFilter filter) final { |
Handle<FixedArrayBase> from(receiver->elements()); |
@@ -758,15 +746,14 @@ class ElementsAccessorBase : public ElementsAccessor { |
// Compute how many elements are not in other. |
uint32_t extra = 0; |
for (uint32_t y = 0; y < len1; y++) { |
- uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); |
- if (ElementsAccessorSubclass::HasElementImpl(receiver, key, from)) { |
- Handle<Object> value; |
- ASSIGN_RETURN_ON_EXCEPTION( |
- isolate, value, |
- ElementsAccessorSubclass::GetImpl(receiver, receiver, key, from), |
- FixedArray); |
+ if (ElementsAccessorSubclass::HasIndexImpl(*from, y)) { |
+ uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); |
+ Handle<Object> value = |
+ ElementsAccessorSubclass::GetImpl(receiver, key, from); |
DCHECK(!value->IsTheHole()); |
+ DCHECK(!value->IsAccessorPair()); |
+ DCHECK(!value->IsExecutableAccessorInfo()); |
if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { |
continue; |
} |
@@ -794,13 +781,12 @@ class ElementsAccessorBase : public ElementsAccessor { |
// Fill in the extra values. |
uint32_t index = 0; |
for (uint32_t y = 0; y < len1; y++) { |
- uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); |
- if (ElementsAccessorSubclass::HasElementImpl(receiver, key, from)) { |
- Handle<Object> value; |
- ASSIGN_RETURN_ON_EXCEPTION( |
- isolate, value, |
- ElementsAccessorSubclass::GetImpl(receiver, receiver, key, from), |
- FixedArray); |
+ if (ElementsAccessorSubclass::HasIndexImpl(*from, y)) { |
+ uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); |
+ Handle<Object> value = |
+ ElementsAccessorSubclass::GetImpl(receiver, key, from); |
+ DCHECK(!value->IsAccessorPair()); |
+ DCHECK(!value->IsExecutableAccessorInfo()); |
if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { |
continue; |
} |
@@ -824,6 +810,14 @@ class ElementsAccessorBase : public ElementsAccessor { |
return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store); |
} |
+ static bool HasIndexImpl(FixedArrayBase* backing_store, uint32_t index) { |
+ return true; |
+ } |
+ |
+ virtual bool HasIndex(FixedArrayBase* backing_store, uint32_t index) final { |
+ return ElementsAccessorSubclass::HasIndexImpl(backing_store, index); |
+ } |
+ |
static uint32_t GetKeyForIndexImpl(FixedArrayBase* backing_store, |
uint32_t index) { |
return index; |
@@ -1008,6 +1002,10 @@ class FastElementsAccessor |
return !Handle<BackingStore>::cast(backing_store)->is_the_hole(key); |
} |
+ static bool HasIndexImpl(FixedArrayBase* backing_store, uint32_t index) { |
+ return !BackingStore::cast(backing_store)->is_the_hole(index); |
+ } |
+ |
static void ValidateContents(Handle<JSObject> holder, int length) { |
#if DEBUG |
Isolate* isolate = holder->GetIsolate(); |
@@ -1284,11 +1282,8 @@ class TypedElementsAccessor |
friend class ElementsAccessorBase<AccessorClass, |
ElementsKindTraits<Kind> >; |
- MUST_USE_RESULT static MaybeHandle<Object> GetImpl( |
- Handle<Object> receiver, |
- Handle<JSObject> obj, |
- uint32_t key, |
- Handle<FixedArrayBase> backing_store) { |
+ static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, |
+ Handle<FixedArrayBase> backing_store) { |
if (key < AccessorClass::GetCapacityImpl(*obj, *backing_store)) { |
return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); |
} else { |
@@ -1296,12 +1291,10 @@ class TypedElementsAccessor |
} |
} |
- MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
- Handle<JSObject> obj, |
- uint32_t key, |
- Handle<FixedArrayBase> backing_store) { |
- return key < AccessorClass::GetCapacityImpl(*obj, *backing_store) ? NONE |
- : ABSENT; |
+ static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key, |
+ FixedArrayBase* backing_store) { |
+ return key < AccessorClass::GetCapacityImpl(obj, backing_store) ? NONE |
+ : ABSENT; |
} |
MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( |
@@ -1481,34 +1474,22 @@ class DictionaryElementsAccessor |
return DeleteCommon(obj, key, language_mode); |
} |
- MUST_USE_RESULT static MaybeHandle<Object> GetImpl( |
- Handle<Object> receiver, |
- Handle<JSObject> obj, |
- uint32_t key, |
- Handle<FixedArrayBase> store) { |
+ static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, |
+ Handle<FixedArrayBase> store) { |
Handle<SeededNumberDictionary> backing_store = |
Handle<SeededNumberDictionary>::cast(store); |
Isolate* isolate = backing_store->GetIsolate(); |
int entry = backing_store->FindEntry(key); |
if (entry != SeededNumberDictionary::kNotFound) { |
- Handle<Object> element(backing_store->ValueAt(entry), isolate); |
- PropertyDetails details = backing_store->DetailsAt(entry); |
- if (details.type() == ACCESSOR_CONSTANT) { |
- return JSObject::GetElementWithCallback( |
- obj, receiver, element, key, obj); |
- } else { |
- return element; |
- } |
+ return handle(backing_store->ValueAt(entry), isolate); |
} |
return isolate->factory()->the_hole_value(); |
} |
- MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
- Handle<JSObject> obj, |
- uint32_t key, |
- Handle<FixedArrayBase> backing_store) { |
- Handle<SeededNumberDictionary> dictionary = |
- Handle<SeededNumberDictionary>::cast(backing_store); |
+ static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key, |
+ FixedArrayBase* backing_store) { |
+ SeededNumberDictionary* dictionary = |
+ SeededNumberDictionary::cast(backing_store); |
int entry = dictionary->FindEntry(key); |
if (entry != SeededNumberDictionary::kNotFound) { |
return dictionary->DetailsAt(entry).attributes(); |
@@ -1516,10 +1497,8 @@ class DictionaryElementsAccessor |
return ABSENT; |
} |
- MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
- Handle<JSObject> obj, |
- uint32_t key, |
- Handle<FixedArrayBase> store) { |
+ static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
+ Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> store) { |
Handle<SeededNumberDictionary> backing_store = |
Handle<SeededNumberDictionary>::cast(store); |
int entry = backing_store->FindEntry(key); |
@@ -1538,6 +1517,13 @@ class DictionaryElementsAccessor |
return backing_store->FindEntry(key) != SeededNumberDictionary::kNotFound; |
} |
+ static bool HasIndexImpl(FixedArrayBase* store, uint32_t index) { |
+ DisallowHeapAllocation no_gc; |
+ SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
+ Object* key = dict->KeyAt(index); |
+ return !key->IsTheHole(); |
+ } |
+ |
static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, uint32_t index) { |
DisallowHeapAllocation no_gc; |
SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
@@ -1575,14 +1561,11 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase< |
SloppyArgumentsElementsAccessor, |
ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >; |
- MUST_USE_RESULT static MaybeHandle<Object> GetImpl( |
- Handle<Object> receiver, |
- Handle<JSObject> obj, |
- uint32_t key, |
- Handle<FixedArrayBase> parameters) { |
+ static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, |
+ Handle<FixedArrayBase> parameters) { |
Isolate* isolate = obj->GetIsolate(); |
Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); |
- Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); |
+ Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate); |
if (!probe->IsTheHole()) { |
DisallowHeapAllocation no_gc; |
Context* context = Context::cast(parameter_map->get(0)); |
@@ -1593,12 +1576,8 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase< |
// Object is not mapped, defer to the arguments. |
Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)), |
isolate); |
- Handle<Object> result; |
- ASSIGN_RETURN_ON_EXCEPTION( |
- isolate, result, |
- ElementsAccessor::ForArray(arguments)->Get( |
- receiver, obj, key, arguments), |
- Object); |
+ Handle<Object> result = |
+ ElementsAccessor::ForArray(arguments)->Get(obj, key, arguments); |
// Elements of the arguments object in slow mode might be slow aliases. |
if (result->IsAliasedArgumentsEntry()) { |
DisallowHeapAllocation no_gc; |
@@ -1613,28 +1592,25 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase< |
} |
} |
- MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
- Handle<JSObject> obj, |
- uint32_t key, |
- Handle<FixedArrayBase> backing_store) { |
- Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store); |
- Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); |
+ static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key, |
+ FixedArrayBase* backing_store) { |
+ FixedArray* parameter_map = FixedArray::cast(backing_store); |
+ Object* probe = GetParameterMapArg(parameter_map, key); |
if (!probe->IsTheHole()) { |
return NONE; |
} else { |
// If not aliased, check the arguments. |
- Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); |
+ FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
return ElementsAccessor::ForArray(arguments) |
->GetAttributes(obj, key, arguments); |
} |
} |
- MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
- Handle<JSObject> obj, |
- uint32_t key, |
- Handle<FixedArrayBase> parameters) { |
+ static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
+ Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> parameters) { |
Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); |
- Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); |
+ Handle<Object> probe(GetParameterMapArg(*parameter_map, key), |
+ obj->GetIsolate()); |
if (!probe->IsTheHole()) { |
return MaybeHandle<AccessorPair>(); |
} else { |
@@ -1659,7 +1635,7 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase< |
Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { |
Isolate* isolate = obj->GetIsolate(); |
Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements())); |
- Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); |
+ Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate); |
if (!probe->IsTheHole()) { |
// TODO(kmillikin): We could check if this was the last aliased |
// parameter, and revert to normal elements in that case. That |
@@ -1692,35 +1668,61 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase< |
FixedArrayBase* backing_store) { |
FixedArray* parameter_map = FixedArray::cast(backing_store); |
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
- return Max(static_cast<uint32_t>(parameter_map->length() - 2), |
- ForArray(arguments)->GetCapacity(holder, arguments)); |
+ return parameter_map->length() - 2 + |
+ ForArray(arguments)->GetCapacity(holder, arguments); |
} |
- static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict, uint32_t index) { |
- return index; |
+ static bool HasIndexImpl(FixedArrayBase* parameters, uint32_t index) { |
+ FixedArray* parameter_map = FixedArray::cast(parameters); |
+ uint32_t length = parameter_map->length() - 2; |
+ if (index < length) { |
+ return !GetParameterMapArg(parameter_map, index)->IsTheHole(); |
+ } |
+ |
+ FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
+ return ForArray(arguments)->HasIndex(arguments, index - length); |
} |
- static uint32_t GetIndexForKeyImpl(FixedArrayBase* dict, uint32_t key) { |
- return key; |
+ static uint32_t GetKeyForIndexImpl(FixedArrayBase* parameters, |
+ uint32_t index) { |
+ FixedArray* parameter_map = FixedArray::cast(parameters); |
+ uint32_t length = parameter_map->length() - 2; |
+ if (index < length) return index; |
+ |
+ FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
+ return ForArray(arguments)->GetKeyForIndex(arguments, index - length); |
} |
- static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, |
- uint32_t index) { |
- return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); |
+ static uint32_t GetIndexForKeyImpl(FixedArrayBase* parameters, uint32_t key) { |
+ FixedArray* parameter_map = FixedArray::cast(parameters); |
+ Object* probe = GetParameterMapArg(parameter_map, key); |
+ if (!probe->IsTheHole()) return key; |
+ |
+ uint32_t length = parameter_map->length() - 2; |
+ FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
+ return length + |
+ ElementsAccessor::ForArray(arguments) |
+ ->GetIndexForKey(arguments, key); |
} |
+ static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters, |
+ uint32_t index) { |
+ FixedArray* parameter_map = FixedArray::cast(parameters); |
+ uint32_t length = parameter_map->length() - 2; |
+ if (index < length) { |
+ return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); |
+ } |
+ index -= length; |
+ FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
+ return ElementsAccessor::ForArray(arguments)->GetDetails(arguments, index); |
+ } |
private: |
- static Handle<Object> GetParameterMapArg(Handle<JSObject> holder, |
- Handle<FixedArray> parameter_map, |
- uint32_t key) { |
- Isolate* isolate = holder->GetIsolate(); |
- uint32_t length = holder->IsJSArray() |
- ? Smi::cast(Handle<JSArray>::cast(holder)->length())->value() |
- : parameter_map->length(); |
- return key < (length - 2) |
- ? handle(parameter_map->get(key + 2), isolate) |
- : Handle<Object>::cast(isolate->factory()->the_hole_value()); |
+ static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) { |
+ uint32_t length = parameter_map->length() - 2; |
+ return key < length |
+ ? parameter_map->get(key + 2) |
+ : Object::cast(parameter_map->GetHeap()->the_hole_value()); |
} |
}; |
@@ -1801,7 +1803,7 @@ MaybeHandle<Object> ElementsAccessorBase<ElementsAccessorSubclass, |
// to slow elements is needed for other reasons. |
if (length->IsNumber()) { |
uint32_t value; |
- if (length->ToArrayIndex(&value)) { |
+ if (length->ToArrayLength(&value)) { |
Handle<SeededNumberDictionary> dictionary = |
JSObject::NormalizeElements(array); |
DCHECK(!dictionary.is_null()); |