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

[array] Fix side-effect for 'from' argument in Array.p.lastIndexOf

This CL fixes a bug if the second argument ('from') for lastIndexOf
changes the array when its converted to an integer.

R=jgruber@chromium.org

Bug: chromium:878845
Change-Id: I8759dd19381c63f0dde1d4c5abc1b6c7291c6048
Reviewed-on: https://chromium-review.googlesource.com/1196507Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Simon Zünd <szuend@google.com>
Cr-Commit-Position: refs/heads/master@{#55525}
parent 789bfeb3
...@@ -72,8 +72,8 @@ module array { ...@@ -72,8 +72,8 @@ module array {
} }
macro TryFastArrayLastIndexOf( macro TryFastArrayLastIndexOf(
context: Context, receiver: Object, context: Context, receiver: JSReceiver, searchElement: Object,
arguments: constexpr Arguments): Object from: Number): Object
labels Slow { labels Slow {
EnsureFastJSArray(context, receiver) otherwise Slow; EnsureFastJSArray(context, receiver) otherwise Slow;
const array: JSArray = unsafe_cast<JSArray>(receiver); const array: JSArray = unsafe_cast<JSArray>(receiver);
...@@ -81,35 +81,21 @@ module array { ...@@ -81,35 +81,21 @@ module array {
const length: Smi = array.length_fast; const length: Smi = array.length_fast;
if (length == 0) return SmiConstant(-1); if (length == 0) return SmiConstant(-1);
const from: Smi = cast<Smi>(GetFromIndex(context, length, arguments)) const fromSmi: Smi = cast<Smi>(from) otherwise Slow;
otherwise Slow;
const kind: ElementsKind = array.map.elements_kind; const kind: ElementsKind = array.map.elements_kind;
if (IsFastSmiOrTaggedElementsKind(kind)) { if (IsFastSmiOrTaggedElementsKind(kind)) {
return FastArrayLastIndexOf<FixedArray>( return FastArrayLastIndexOf<FixedArray>(
context, array, length, from, arguments[0]); context, array, length, fromSmi, searchElement);
} }
assert(IsDoubleElementsKind(kind)); assert(IsDoubleElementsKind(kind));
return FastArrayLastIndexOf<FixedDoubleArray>( return FastArrayLastIndexOf<FixedDoubleArray>(
context, array, length, from, arguments[0]); context, array, length, fromSmi, searchElement);
} }
macro GenericArrayLastIndexOf( macro GenericArrayLastIndexOf(
context: Context, receiver: Object, context: Context, object: JSReceiver, searchElement: Object,
arguments: constexpr Arguments): Object { from: Number): Object {
// 1. Let O be ? ToObject(this value). let k: Number = from;
const object: JSReceiver = ToObject_Inline(context, receiver);
// 2. Let len be ? ToLength(? Get(O, "length")).
const length: Number = GetLengthProperty(context, object);
// 3. If len is 0, return -1.
if (length == SmiConstant(0)) return SmiConstant(-1);
const search_element: Object = arguments[0];
// Step 4 - 6.
let k: Number = GetFromIndex(context, length, arguments);
// 7. Repeat, while k >= 0. // 7. Repeat, while k >= 0.
while (k >= 0) { while (k >= 0) {
...@@ -123,7 +109,7 @@ module array { ...@@ -123,7 +109,7 @@ module array {
// ii. Let same be the result of performing Strict Equality Comparison // ii. Let same be the result of performing Strict Equality Comparison
// searchElement === elementK. // searchElement === elementK.
const same: Boolean = StrictEqual(search_element, element); const same: Boolean = StrictEqual(searchElement, element);
// iii. If same is true, return k. // iii. If same is true, return k.
if (same == True) return k; if (same == True) return k;
...@@ -140,12 +126,26 @@ module array { ...@@ -140,12 +126,26 @@ module array {
// https://tc39.github.io/ecma262/#sec-array.prototype.lastIndexOf // https://tc39.github.io/ecma262/#sec-array.prototype.lastIndexOf
javascript builtin ArrayPrototypeLastIndexOf( javascript builtin ArrayPrototypeLastIndexOf(
context: Context, receiver: Object, ...arguments): Object { context: Context, receiver: Object, ...arguments): Object {
// 1. Let O be ? ToObject(this value).
const object: JSReceiver = ToObject_Inline(context, receiver);
// 2. Let len be ? ToLength(? Get(O, "length")).
const length: Number = GetLengthProperty(context, object);
// 3. If len is 0, return -1.
if (length == SmiConstant(0)) return SmiConstant(-1);
// Step 4 - 6.
const from: Number = GetFromIndex(context, length, arguments);
const searchElement: Object = arguments[0];
try { try {
return TryFastArrayLastIndexOf(context, receiver, arguments) return TryFastArrayLastIndexOf(context, object, searchElement, from)
otherwise Baseline; otherwise Baseline;
} }
label Baseline { label Baseline {
return GenericArrayLastIndexOf(context, receiver, arguments); return GenericArrayLastIndexOf(context, object, searchElement, from);
} }
} }
} }
// 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.
let arr = [, 0.1];
Array.prototype.lastIndexOf.call(arr, 100, {
valueOf() {
arr.length = 0;
}
});
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