Commit 5b92f91c authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[elements] handle OOB-holes in Array.prototype.includes fast-path

In the ElementsAccessor fast-path for Array.prototype.includes, we
iterate backing-store elements according to start and length numbers
which might or might not be within the JSArray::length field, for
example when side-effects changed the receiver while start and length
are computed. So even when we have a packed ElementsKind, we might still
observe the hole. This is fine, since logical out-of-bounds accesses
are safe in this case, but it means we must not rely on the
ElementsKind telling us if we can encounter holes.

Bug: chromium:897098
Change-Id: I17db38246aef6edbdd5cee30598cbf7619aba6d8
Reviewed-on: https://chromium-review.googlesource.com/c/1293571Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56884}
parent 351620dc
......@@ -2297,39 +2297,29 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
if (!value->IsNumber()) {
if (value == undefined) {
// Only PACKED_ELEMENTS, HOLEY_ELEMENTS, HOLEY_SMI_ELEMENTS, and
// HOLEY_DOUBLE_ELEMENTS can have `undefined` as a value.
if (!IsObjectElementsKind(Subclass::kind()) &&
!IsHoleyElementsKind(Subclass::kind())) {
return Just(false);
}
// Search for `undefined` or The Hole in PACKED_ELEMENTS,
// HOLEY_ELEMENTS or HOLEY_SMI_ELEMENTS
// Search for `undefined` or The Hole. Even in the case of
// PACKED_DOUBLE_ELEMENTS or PACKED_SMI_ELEMENTS, we might encounter The
// Hole here, since the {length} used here can be larger than
// JSArray::length.
if (IsSmiOrObjectElementsKind(Subclass::kind())) {
auto elements = FixedArray::cast(receiver->elements());
for (uint32_t k = start_from; k < length; ++k) {
Object* element_k = elements->get(k);
if (IsHoleyElementsKind(Subclass::kind()) &&
element_k == the_hole) {
return Just(true);
}
if (IsObjectElementsKind(Subclass::kind()) &&
element_k == undefined) {
if (element_k == the_hole || element_k == undefined) {
return Just(true);
}
}
return Just(false);
} else {
// Search for The Hole in HOLEY_DOUBLE_ELEMENTS
DCHECK_EQ(Subclass::kind(), HOLEY_DOUBLE_ELEMENTS);
// Search for The Hole in HOLEY_DOUBLE_ELEMENTS or
// PACKED_DOUBLE_ELEMENTS.
DCHECK(IsDoubleElementsKind(Subclass::kind()));
auto elements = FixedDoubleArray::cast(receiver->elements());
for (uint32_t k = start_from; k < length; ++k) {
if (IsHoleyElementsKind(Subclass::kind()) &&
elements->is_the_hole(k)) {
if (elements->is_the_hole(k)) {
return Just(true);
}
}
......@@ -2349,7 +2339,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
for (uint32_t k = start_from; k < length; ++k) {
Object* element_k = elements->get(k);
if (IsHoleyElementsKind(Subclass::kind()) && element_k == the_hole) {
if (element_k == the_hole) {
continue;
}
......@@ -2367,8 +2357,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
auto elements = FixedDoubleArray::cast(receiver->elements());
for (uint32_t k = start_from; k < length; ++k) {
if (IsHoleyElementsKind(Subclass::kind()) &&
elements->is_the_hole(k)) {
if (elements->is_the_hole(k)) {
continue;
}
if (elements->get_scalar(k) == search_value) return Just(true);
......@@ -2400,8 +2389,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
auto elements = FixedDoubleArray::cast(receiver->elements());
for (uint32_t k = start_from; k < length; ++k) {
if (IsHoleyElementsKind(Subclass::kind()) &&
elements->is_the_hole(k)) {
if (elements->is_the_hole(k)) {
continue;
}
if (std::isnan(elements->get_scalar(k))) return Just(true);
......
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const arr = [1.1,2.2,3.3];
arr.pop();
const start = {toString: function() {arr.pop();}}
arr.includes(0, start);
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