Commit bc017d81 authored by Simon Zünd's avatar Simon Zünd Committed by Commit Bot

[array] Change array indices handling for proxies in sort preprocessing

For JSProxies we filled a FixedArray with the numbers from 0 to
length - 1. Because all indices were assumed to be Smis, large array
indices on Proxies were not handled correctly.

R=jgruber@chromium.org

Bug: chromium:866314
Change-Id: I6a792e800f31617a6092b219ec82b0e05a83bf7b
Reviewed-on: https://chromium-review.googlesource.com/1146562Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Simon Zünd <szuend@google.com>
Cr-Commit-Position: refs/heads/master@{#54603}
parent 17071e87
......@@ -61,20 +61,14 @@ Object* RemoveArrayHolesGeneric(Isolate* isolate, Handle<JSReceiver> receiver,
// For proxies, we do not collect the keys, instead we use all indices in
// the full range of [0, limit).
Handle<FixedArray> keys;
if (receiver->IsJSProxy()) {
CHECK(Smi::IsValid(limit));
keys = isolate->factory()->NewFixedArray(limit);
for (uint32_t i = 0; i < limit; ++i) {
keys->set(i, Smi::FromInt(i));
}
} else {
if (!receiver->IsJSProxy()) {
keys = JSReceiver::GetOwnElementIndices(isolate, receiver,
Handle<JSObject>::cast(receiver));
}
uint32_t num_undefined = 0;
uint32_t current_pos = 0;
int num_indices = keys->length();
int num_indices = keys.is_null() ? limit : keys->length();
// Compact keys with undefined values and moves non-undefined
// values to the front.
......@@ -86,7 +80,7 @@ Object* RemoveArrayHolesGeneric(Isolate* isolate, Handle<JSReceiver> receiver,
// Holes and 'undefined' are considered free spots.
// A hole is when HasElement(receiver, key) is false.
for (int i = 0; i < num_indices; ++i) {
uint32_t key = NumberToUint32(keys->get(i));
uint32_t key = keys.is_null() ? i : NumberToUint32(keys->get(i));
// We only care about array indices that are smaller than the limit.
// The keys are sorted, so we can break as soon as we encounter the first.
......@@ -143,7 +137,7 @@ Object* RemoveArrayHolesGeneric(Isolate* isolate, Handle<JSReceiver> receiver,
// Deleting everything after the undefineds up unto the limit.
for (int i = num_indices - 1; i >= 0; --i) {
uint32_t key = NumberToUint32(keys->get(i));
uint32_t key = keys.is_null() ? i : NumberToUint32(keys->get(i));
if (key < current_pos) break;
if (key >= limit) continue;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment