[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/1146562 Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Simon Zünd <szuend@google.com> Cr-Commit-Position: refs/heads/master@{#54603}
This commit is contained in:
parent
17071e8720
commit
bc017d81d6
@ -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
|
// For proxies, we do not collect the keys, instead we use all indices in
|
||||||
// the full range of [0, limit).
|
// the full range of [0, limit).
|
||||||
Handle<FixedArray> keys;
|
Handle<FixedArray> keys;
|
||||||
if (receiver->IsJSProxy()) {
|
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 {
|
|
||||||
keys = JSReceiver::GetOwnElementIndices(isolate, receiver,
|
keys = JSReceiver::GetOwnElementIndices(isolate, receiver,
|
||||||
Handle<JSObject>::cast(receiver));
|
Handle<JSObject>::cast(receiver));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t num_undefined = 0;
|
uint32_t num_undefined = 0;
|
||||||
uint32_t current_pos = 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
|
// Compact keys with undefined values and moves non-undefined
|
||||||
// values to the front.
|
// values to the front.
|
||||||
@ -86,7 +80,7 @@ Object* RemoveArrayHolesGeneric(Isolate* isolate, Handle<JSReceiver> receiver,
|
|||||||
// Holes and 'undefined' are considered free spots.
|
// Holes and 'undefined' are considered free spots.
|
||||||
// A hole is when HasElement(receiver, key) is false.
|
// A hole is when HasElement(receiver, key) is false.
|
||||||
for (int i = 0; i < num_indices; ++i) {
|
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.
|
// 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.
|
// 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.
|
// Deleting everything after the undefineds up unto the limit.
|
||||||
for (int i = num_indices - 1; i >= 0; --i) {
|
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 < current_pos) break;
|
||||||
if (key >= limit) continue;
|
if (key >= limit) continue;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user