Commit 7cd01ed3 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Fix bug in reduction of typed array iteration

Typed array iteration throws a TypeError if the receiver is not
a typed array. The JSCallReducer didn't take that into account.

Bug: chromium:1067544
Change-Id: Ib065ba1b7881dc0b62242fc416fa16023a7fa244
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2135632Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Auto-Submit: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67010}
parent 2b047a58
......@@ -4118,11 +4118,14 @@ Reduction JSCallReducer::ReduceJSCall(Node* node,
case Builtins::kArrayPrototypeSlice:
return ReduceArrayPrototypeSlice(node);
case Builtins::kArrayPrototypeEntries:
return ReduceArrayIterator(node, IterationKind::kEntries);
return ReduceArrayIterator(node, ArrayIteratorKind::kArrayLike,
IterationKind::kEntries);
case Builtins::kArrayPrototypeKeys:
return ReduceArrayIterator(node, IterationKind::kKeys);
return ReduceArrayIterator(node, ArrayIteratorKind::kArrayLike,
IterationKind::kKeys);
case Builtins::kArrayPrototypeValues:
return ReduceArrayIterator(node, IterationKind::kValues);
return ReduceArrayIterator(node, ArrayIteratorKind::kArrayLike,
IterationKind::kValues);
case Builtins::kArrayIteratorPrototypeNext:
return ReduceArrayIteratorPrototypeNext(node);
case Builtins::kArrayIsArray:
......@@ -4323,11 +4326,14 @@ Reduction JSCallReducer::ReduceJSCall(Node* node,
case Builtins::kStringPrototypeConcat:
return ReduceStringPrototypeConcat(node);
case Builtins::kTypedArrayPrototypeEntries:
return ReduceArrayIterator(node, IterationKind::kEntries);
return ReduceArrayIterator(node, ArrayIteratorKind::kTypedArray,
IterationKind::kEntries);
case Builtins::kTypedArrayPrototypeKeys:
return ReduceArrayIterator(node, IterationKind::kKeys);
return ReduceArrayIterator(node, ArrayIteratorKind::kTypedArray,
IterationKind::kKeys);
case Builtins::kTypedArrayPrototypeValues:
return ReduceArrayIterator(node, IterationKind::kValues);
return ReduceArrayIterator(node, ArrayIteratorKind::kTypedArray,
IterationKind::kValues);
case Builtins::kPromisePrototypeCatch:
return ReducePromisePrototypeCatch(node);
case Builtins::kPromisePrototypeFinally:
......@@ -5490,7 +5496,9 @@ Reduction JSCallReducer::ReduceArrayIsArray(Node* node) {
return Changed(node);
}
Reduction JSCallReducer::ReduceArrayIterator(Node* node, IterationKind kind) {
Reduction JSCallReducer::ReduceArrayIterator(Node* node,
ArrayIteratorKind array_kind,
IterationKind iteration_kind) {
DisallowHeapAccessIf disallow_heap_access(should_disallow_heap_access());
DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
......@@ -5505,6 +5513,13 @@ Reduction JSCallReducer::ReduceArrayIterator(Node* node, IterationKind kind) {
return NoChange();
}
// TypedArray iteration is stricter: it throws if the receiver is not a typed
// array. So don't bother optimizing in that case.
if (array_kind == ArrayIteratorKind::kTypedArray &&
!inference.AllOfInstanceTypesAre(InstanceType::JS_TYPED_ARRAY_TYPE)) {
return NoChange();
}
// Morph the {node} into a JSCreateArrayIterator with the given {kind}.
RelaxControls(node);
node->ReplaceInput(0, receiver);
......@@ -5512,7 +5527,8 @@ Reduction JSCallReducer::ReduceArrayIterator(Node* node, IterationKind kind) {
node->ReplaceInput(2, effect);
node->ReplaceInput(3, control);
node->TrimInputCount(4);
NodeProperties::ChangeOp(node, javascript()->CreateArrayIterator(kind));
NodeProperties::ChangeOp(node,
javascript()->CreateArrayIterator(iteration_kind));
return Changed(node);
}
......
......@@ -106,8 +106,9 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
const SharedFunctionInfoRef& shared);
Reduction ReduceArraySome(Node* node, const SharedFunctionInfoRef& shared);
enum class ArrayIteratorKind { kArray, kTypedArray };
Reduction ReduceArrayIterator(Node* node, IterationKind kind);
enum class ArrayIteratorKind { kArrayLike, kTypedArray };
Reduction ReduceArrayIterator(Node* node, ArrayIteratorKind array_kind,
IterationKind iteration_kind);
Reduction ReduceArrayIteratorPrototypeNext(Node* node);
Reduction ReduceFastArrayIteratorNext(InstanceType type, Node* node,
IterationKind kind);
......
// Copyright 2020 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
const v = [];
function foo() {
Int8Array.prototype.values.call([v]);
}
%PrepareFunctionForOptimization(foo);
assertThrows(foo, TypeError);
assertThrows(foo, TypeError);
%OptimizeFunctionOnNextCall(foo);
assertThrows(foo, TypeError);
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