[csa] Fix parameter casting on empty arrays

Changes the Array(Includes|IndexOf)(Holey|Packed)Doubles builtins to
first check the input array is not empty before attempting to cast it to
a FixedDoubleArray as an empty array of doubles can be backed by a
FixedArray.

Bug: chromium:1004061
Change-Id: I12f302afa9596fb8a5581849662cd67fcc06f92b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1806676
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Commit-Queue: Dan Elphick <delphick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63794}
This commit is contained in:
Dan Elphick 2019-09-16 13:36:15 +01:00 committed by Commit Bot
parent e35175a764
commit bec49d81df
2 changed files with 74 additions and 8 deletions

View File

@ -822,6 +822,13 @@ class ArrayIncludesIndexofAssembler : public CodeStubAssembler {
TNode<FixedDoubleArray> elements,
TNode<Object> search_element,
TNode<Smi> array_length, TNode<Smi> from_index);
void ReturnIfEmpty(TNode<Smi> length, TNode<Object> value) {
Label done(this);
GotoIf(SmiGreaterThan(length, SmiConstant(0)), &done);
Return(value);
BIND(&done);
}
};
void ArrayIncludesIndexofAssembler::Generate(SearchVariant variant,
@ -1324,22 +1331,24 @@ TF_BUILTIN(ArrayIncludesSmiOrObject, ArrayIncludesIndexofAssembler) {
}
TF_BUILTIN(ArrayIncludesPackedDoubles, ArrayIncludesIndexofAssembler) {
TNode<FixedDoubleArray> elements = CAST(Parameter(Descriptor::kElements));
TNode<FixedArrayBase> elements = CAST(Parameter(Descriptor::kElements));
TNode<Object> search_element = CAST(Parameter(Descriptor::kSearchElement));
TNode<Smi> array_length = CAST(Parameter(Descriptor::kLength));
TNode<Smi> from_index = CAST(Parameter(Descriptor::kFromIndex));
GeneratePackedDoubles(kIncludes, elements, search_element, array_length,
ReturnIfEmpty(array_length, FalseConstant());
GeneratePackedDoubles(kIncludes, CAST(elements), search_element, array_length,
from_index);
}
TF_BUILTIN(ArrayIncludesHoleyDoubles, ArrayIncludesIndexofAssembler) {
TNode<FixedDoubleArray> elements = CAST(Parameter(Descriptor::kElements));
TNode<FixedArrayBase> elements = CAST(Parameter(Descriptor::kElements));
TNode<Object> search_element = CAST(Parameter(Descriptor::kSearchElement));
TNode<Smi> array_length = CAST(Parameter(Descriptor::kLength));
TNode<Smi> from_index = CAST(Parameter(Descriptor::kFromIndex));
GenerateHoleyDoubles(kIncludes, elements, search_element, array_length,
ReturnIfEmpty(array_length, FalseConstant());
GenerateHoleyDoubles(kIncludes, CAST(elements), search_element, array_length,
from_index);
}
@ -1363,22 +1372,24 @@ TF_BUILTIN(ArrayIndexOfSmiOrObject, ArrayIncludesIndexofAssembler) {
}
TF_BUILTIN(ArrayIndexOfPackedDoubles, ArrayIncludesIndexofAssembler) {
TNode<FixedDoubleArray> elements = CAST(Parameter(Descriptor::kElements));
TNode<FixedArrayBase> elements = CAST(Parameter(Descriptor::kElements));
TNode<Object> search_element = CAST(Parameter(Descriptor::kSearchElement));
TNode<Smi> array_length = CAST(Parameter(Descriptor::kLength));
TNode<Smi> from_index = CAST(Parameter(Descriptor::kFromIndex));
GeneratePackedDoubles(kIndexOf, elements, search_element, array_length,
ReturnIfEmpty(array_length, NumberConstant(-1));
GeneratePackedDoubles(kIndexOf, CAST(elements), search_element, array_length,
from_index);
}
TF_BUILTIN(ArrayIndexOfHoleyDoubles, ArrayIncludesIndexofAssembler) {
TNode<FixedDoubleArray> elements = CAST(Parameter(Descriptor::kElements));
TNode<FixedArrayBase> elements = CAST(Parameter(Descriptor::kElements));
TNode<Object> search_element = CAST(Parameter(Descriptor::kSearchElement));
TNode<Smi> array_length = CAST(Parameter(Descriptor::kLength));
TNode<Smi> from_index = CAST(Parameter(Descriptor::kFromIndex));
GenerateHoleyDoubles(kIndexOf, elements, search_element, array_length,
ReturnIfEmpty(array_length, NumberConstant(-1));
GenerateHoleyDoubles(kIndexOf, CAST(elements), search_element, array_length,
from_index);
}

View File

@ -0,0 +1,55 @@
// Copyright 2019 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.
// Flags: --allow-natives-syntax
(function testPackedDoublesIncludes() {
arr = [1.5, 2.5];
arr.length = 0;
function f() {
return arr.includes(1);
};
%PrepareFunctionForOptimization(f);
assertEquals(f(), false);
%OptimizeFunctionOnNextCall(f);
assertEquals(f(), false);
})();
(function testHoleyDoublesIncludes() {
arr = [1.1];
arr[3]= 1.5;
arr.length = 0;
function f() {
return arr.includes(1);
};
%PrepareFunctionForOptimization(f);
assertEquals(f(), false);
%OptimizeFunctionOnNextCall(f);
assertEquals(f(), false);
})();
(function testPackedDoublesIndexOf() {
arr = [1.5, 2.5];
arr.length = 0;
function f() {
return arr.indexOf(1);
};
%PrepareFunctionForOptimization(f);
assertEquals(f(), -1);
%OptimizeFunctionOnNextCall(f);
assertEquals(f(), -1);
})();
(function testHoleyDoublesIndexOf() {
arr = [1.1];
arr[3]= 1.5;
arr.length = 0;
function f() {
return arr.indexOf(1);
};
%PrepareFunctionForOptimization(f);
assertEquals(f(), -1);
%OptimizeFunctionOnNextCall(f);
assertEquals(f(), -1);
})();