Fix array.indexOf for negative fromIndex

Array.indexOf accepts an optional fromIndex argument. When non-negative,
this argument restricts the searched indices to those starting at
fromIndex:
[1, 2, 1].indexOf(1,1) == 2
When negative, it is meant to be added to the array length to provide
such initial index for the search:
[1, 2, 1].indexOf(1, -2) == 2

This transformation has been done by the non-optimised builtin but not
by the reducer. The CL adds this construction to the reducer.

Bug: chromium:842612
Change-Id: I0ff089997f4ebb4dc3c2923e52c382a8a96cd711
Reviewed-on: https://chromium-review.googlesource.com/1059628
Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
Commit-Queue: Vaclav Brozek <vabr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53197}
This commit is contained in:
Vaclav Brozek 2018-05-15 12:54:43 -04:00 committed by Commit Bot
parent 7485b1296b
commit be5cfb2295
2 changed files with 30 additions and 2 deletions

View File

@ -2557,8 +2557,20 @@ Reduction JSCallReducer::ReduceArrayIndexOfIncludes(
Node* new_from_index = jsgraph()->ZeroConstant();
if (node->op()->ValueInputCount() >= 4) {
Node* from_index = NodeProperties::GetValueInput(node, 3);
new_from_index = effect = graph()->NewNode(
simplified()->CheckSmi(p.feedback()), from_index, effect, control);
from_index = effect = graph()->NewNode(simplified()->CheckSmi(p.feedback()),
from_index, effect, control);
// If the index is negative, it means the offset from the end and therefore
// needs to be added to the length. If the result is still negative, it
// needs to be clamped to 0.
new_from_index = graph()->NewNode(
common()->Select(MachineRepresentation::kTagged, BranchHint::kFalse),
graph()->NewNode(simplified()->NumberLessThan(), from_index,
jsgraph()->ZeroConstant()),
graph()->NewNode(
simplified()->NumberMax(),
graph()->NewNode(simplified()->NumberAdd(), length, from_index),
jsgraph()->ZeroConstant()),
from_index);
}
Node* context = NodeProperties::GetContextInput(node);

View File

@ -0,0 +1,16 @@
// 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.
// Flags: --allow-natives-syntax
var arr = [undefined];
function f() {
assertEquals(0, arr.indexOf(undefined, -1));
}
f();
f();
%OptimizeFunctionOnNextCall(f);
f();