[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/+/2135632 Reviewed-by: Maya 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}
This commit is contained in:
parent
2b047a58f8
commit
7cd01ed3c1
@ -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);
|
||||
|
16
test/mjsunit/compiler/regress-1067544.js
Normal file
16
test/mjsunit/compiler/regress-1067544.js
Normal file
@ -0,0 +1,16 @@
|
||||
// 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);
|
Loading…
Reference in New Issue
Block a user