[rab/gsab] Fix %TypedArray%.from
Bug: v8:11111, chromium:1378900 Change-Id: I01548502e9aa101e9e60bae01d9b24f8aa417bca Fixed: chromium:1378900 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3991492 Auto-Submit: Marja Hölttä <marja@chromium.org> Reviewed-by: Shu-yu Guo <syg@chromium.org> Commit-Queue: Marja Hölttä <marja@chromium.org> Cr-Commit-Position: refs/heads/main@{#84004}
This commit is contained in:
parent
9d0de43f39
commit
1e463aca7c
@ -104,8 +104,9 @@ TypedArrayFrom(js-implicit context: NativeContext, receiver: JSAny)(
|
||||
finalSource = source;
|
||||
}
|
||||
case (sourceTypedArray: JSTypedArray): {
|
||||
const sourceBuffer = sourceTypedArray.buffer;
|
||||
if (IsDetachedBuffer(sourceBuffer)) goto UseUserProvidedIterator;
|
||||
finalLength =
|
||||
LoadJSTypedArrayLengthAndCheckDetached(sourceTypedArray)
|
||||
otherwise UseUserProvidedIterator;
|
||||
|
||||
// Check that the iterator function is exactly
|
||||
// Builtin::kTypedArrayPrototypeValues.
|
||||
@ -117,7 +118,6 @@ TypedArrayFrom(js-implicit context: NativeContext, receiver: JSAny)(
|
||||
// Source is a TypedArray with unmodified iterator behavior. Use the
|
||||
// source object directly, taking advantage of the special-case code
|
||||
// in TypedArrayCopyElements
|
||||
finalLength = sourceTypedArray.length;
|
||||
finalSource = source;
|
||||
}
|
||||
case (Object): {
|
||||
|
@ -3974,10 +3974,8 @@ class TypedElementsAccessor
|
||||
CHECK(!out_of_bounds);
|
||||
Handle<JSTypedArray> source_ta = Handle<JSTypedArray>::cast(source);
|
||||
ElementsKind source_kind = source_ta->GetElementsKind();
|
||||
bool source_is_bigint =
|
||||
source_kind == BIGINT64_ELEMENTS || source_kind == BIGUINT64_ELEMENTS;
|
||||
bool target_is_bigint =
|
||||
Kind == BIGINT64_ELEMENTS || Kind == BIGUINT64_ELEMENTS;
|
||||
bool source_is_bigint = IsBigIntTypedArrayElementsKind(source_kind);
|
||||
bool target_is_bigint = IsBigIntTypedArrayElementsKind(Kind);
|
||||
// If we have to copy more elements than we have in the source, we need to
|
||||
// do special handling and conversion; that happens in the slow case.
|
||||
if (source_is_bigint == target_is_bigint && !source_ta->WasDetached() &&
|
||||
|
@ -2,8 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony-rab-gsab --allow-natives-syntax
|
||||
// Flags: --harmony-relative-indexing-methods --harmony-array-find-last
|
||||
// Flags: --harmony-rab-gsab --allow-natives-syntax --harmony-array-find-last
|
||||
|
||||
"use strict";
|
||||
|
||||
@ -142,6 +141,25 @@ d8.file.execute('test/mjsunit/typedarray-helpers.js');
|
||||
assertEquals([3, 4, 5, 6],
|
||||
ToNumbers(new targetCtor(lengthTrackingWithOffset)));
|
||||
});
|
||||
|
||||
AllBigIntUnmatchedCtorCombinations((targetCtor, sourceCtor) => {
|
||||
const gsab = CreateGrowableSharedArrayBuffer(
|
||||
4 * sourceCtor.BYTES_PER_ELEMENT,
|
||||
8 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
const fixedLength = new sourceCtor(gsab, 0, 4);
|
||||
const fixedLengthWithOffset = new sourceCtor(
|
||||
gsab, 2 * sourceCtor.BYTES_PER_ELEMENT, 2);
|
||||
const lengthTracking = new sourceCtor(gsab, 0);
|
||||
const lengthTrackingWithOffset = new sourceCtor(
|
||||
gsab, 2 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
|
||||
assertThrows(() => { new targetCtor(fixedLength); }, TypeError);
|
||||
assertThrows(() => { new targetCtor(fixedLengthWithOffset); }, TypeError);
|
||||
assertThrows(() => { new targetCtor(lengthTracking); }, TypeError);
|
||||
assertThrows(() => { new targetCtor(lengthTrackingWithOffset); },
|
||||
TypeError);
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
(function ConstructFromTypedArraySpeciesConstructorNotCalled() {
|
||||
@ -3907,3 +3925,72 @@ SortCallbackGrows(ArraySortHelper);
|
||||
ToNumbers(func.apply(null, lengthTrackingWithOffset)));
|
||||
}
|
||||
})();
|
||||
|
||||
(function TypedArrayFrom() {
|
||||
AllBigIntMatchedCtorCombinations((targetCtor, sourceCtor) => {
|
||||
const gsab = CreateGrowableSharedArrayBuffer(
|
||||
4 * sourceCtor.BYTES_PER_ELEMENT,
|
||||
8 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
const fixedLength = new sourceCtor(gsab, 0, 4);
|
||||
const fixedLengthWithOffset = new sourceCtor(
|
||||
gsab, 2 * sourceCtor.BYTES_PER_ELEMENT, 2);
|
||||
const lengthTracking = new sourceCtor(gsab, 0);
|
||||
const lengthTrackingWithOffset = new sourceCtor(
|
||||
gsab, 2 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
|
||||
// Write some data into the array.
|
||||
const taFull = new sourceCtor(gsab);
|
||||
for (let i = 0; i < 4; ++i) {
|
||||
WriteToTypedArray(taFull, i, i + 1);
|
||||
}
|
||||
|
||||
// Orig. array: [1, 2, 3, 4]
|
||||
// [1, 2, 3, 4] << fixedLength
|
||||
// [3, 4] << fixedLengthWithOffset
|
||||
// [1, 2, 3, 4, ...] << lengthTracking
|
||||
// [3, 4, ...] << lengthTrackingWithOffset
|
||||
|
||||
assertEquals([1, 2, 3, 4], ToNumbers(targetCtor.from(fixedLength)));
|
||||
assertEquals([3, 4], ToNumbers(targetCtor.from(fixedLengthWithOffset)));
|
||||
assertEquals([1, 2, 3, 4], ToNumbers(targetCtor.from(lengthTracking)));
|
||||
assertEquals([3, 4], ToNumbers(targetCtor.from(lengthTrackingWithOffset)));
|
||||
|
||||
// Grow.
|
||||
gsab.grow(6 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
|
||||
for (let i = 0; i < 6; ++i) {
|
||||
WriteToTypedArray(taFull, i, i + 1);
|
||||
}
|
||||
|
||||
// Orig. array: [1, 2, 3, 4, 5, 6]
|
||||
// [1, 2, 3, 4] << fixedLength
|
||||
// [3, 4] << fixedLengthWithOffset
|
||||
// [1, 2, 3, 4, 5, 6, ...] << lengthTracking
|
||||
// [3, 4, 5, 6, ...] << lengthTrackingWithOffset
|
||||
|
||||
assertEquals([1, 2, 3, 4], ToNumbers(targetCtor.from(fixedLength)));
|
||||
assertEquals([3, 4], ToNumbers(targetCtor.from(fixedLengthWithOffset)));
|
||||
assertEquals([1, 2, 3, 4, 5, 6],
|
||||
ToNumbers(targetCtor.from(lengthTracking)));
|
||||
assertEquals([3, 4, 5, 6],
|
||||
ToNumbers(targetCtor.from(lengthTrackingWithOffset)));
|
||||
});
|
||||
|
||||
AllBigIntUnmatchedCtorCombinations((targetCtor, sourceCtor) => {
|
||||
const gsab = CreateGrowableSharedArrayBuffer(
|
||||
4 * sourceCtor.BYTES_PER_ELEMENT,
|
||||
8 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
const fixedLength = new sourceCtor(gsab, 0, 4);
|
||||
const fixedLengthWithOffset = new sourceCtor(
|
||||
gsab, 2 * sourceCtor.BYTES_PER_ELEMENT, 2);
|
||||
const lengthTracking = new sourceCtor(gsab, 0);
|
||||
const lengthTrackingWithOffset = new sourceCtor(
|
||||
gsab, 2 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
|
||||
assertThrows(() => { targetCtor.from(fixedLength); }, TypeError);
|
||||
assertThrows(() => { targetCtor.from(fixedLengthWithOffset); }, TypeError);
|
||||
assertThrows(() => { targetCtor.from(lengthTracking); }, TypeError);
|
||||
assertThrows(() => { targetCtor.from(lengthTrackingWithOffset); },
|
||||
TypeError);
|
||||
});
|
||||
})();
|
||||
|
@ -91,6 +91,18 @@ function AllBigIntMatchedCtorCombinations(test) {
|
||||
}
|
||||
}
|
||||
|
||||
function AllBigIntUnmatchedCtorCombinations(test) {
|
||||
for (let targetCtor of ctors) {
|
||||
for (let sourceCtor of ctors) {
|
||||
if (IsBigIntTypedArray(new targetCtor()) ==
|
||||
IsBigIntTypedArray(new sourceCtor())) {
|
||||
continue;
|
||||
}
|
||||
test(targetCtor, sourceCtor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ReadDataFromBuffer(ab, ctor) {
|
||||
let result = [];
|
||||
const ta = new ctor(ab, 0, ab.byteLength / ctor.BYTES_PER_ELEMENT);
|
||||
|
@ -1763,3 +1763,45 @@ function AtParameterConversionDetaches(atHelper) {
|
||||
}
|
||||
AtParameterConversionDetaches(TypedArrayAtHelper);
|
||||
AtParameterConversionDetaches(ArrayAtHelper);
|
||||
|
||||
(function TypedArrayFrom() {
|
||||
AllBigIntMatchedCtorCombinations((targetCtor, sourceCtor) => {
|
||||
const rab = CreateResizableArrayBuffer(
|
||||
4 * sourceCtor.BYTES_PER_ELEMENT,
|
||||
8 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
const fixedLength = new sourceCtor(rab, 0, 4);
|
||||
const fixedLengthWithOffset = new sourceCtor(
|
||||
rab, 2 * sourceCtor.BYTES_PER_ELEMENT, 2);
|
||||
const lengthTracking = new sourceCtor(rab, 0);
|
||||
const lengthTrackingWithOffset = new sourceCtor(
|
||||
rab, 2 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
|
||||
%ArrayBufferDetach(rab);
|
||||
|
||||
assertThrows(() => { targetCtor.from(fixedLength); }, TypeError);
|
||||
assertThrows(() => { targetCtor.from(fixedLengthWithOffset); }, TypeError);
|
||||
assertThrows(() => { targetCtor.from(lengthTracking); }, TypeError);
|
||||
assertThrows(() => { targetCtor.from(lengthTrackingWithOffset); },
|
||||
TypeError);
|
||||
});
|
||||
|
||||
AllBigIntUnmatchedCtorCombinations((targetCtor, sourceCtor) => {
|
||||
const rab = CreateResizableArrayBuffer(
|
||||
4 * sourceCtor.BYTES_PER_ELEMENT,
|
||||
8 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
const fixedLength = new sourceCtor(rab, 0, 4);
|
||||
const fixedLengthWithOffset = new sourceCtor(
|
||||
rab, 2 * sourceCtor.BYTES_PER_ELEMENT, 2);
|
||||
const lengthTracking = new sourceCtor(rab, 0);
|
||||
const lengthTrackingWithOffset = new sourceCtor(
|
||||
rab, 2 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
|
||||
%ArrayBufferDetach(rab);
|
||||
|
||||
assertThrows(() => { targetCtor.from(fixedLength); }, TypeError);
|
||||
assertThrows(() => { targetCtor.from(fixedLengthWithOffset); }, TypeError);
|
||||
assertThrows(() => { targetCtor.from(lengthTracking); }, TypeError);
|
||||
assertThrows(() => { targetCtor.from(lengthTrackingWithOffset); },
|
||||
TypeError);
|
||||
});
|
||||
})();
|
||||
|
@ -172,6 +172,24 @@ d8.file.execute('test/mjsunit/typedarray-helpers.js');
|
||||
assertEquals([3, 4, 5, 6],
|
||||
ToNumbers(new targetCtor(lengthTrackingWithOffset)));
|
||||
});
|
||||
|
||||
AllBigIntUnmatchedCtorCombinations((targetCtor, sourceCtor) => {
|
||||
const rab = CreateResizableArrayBuffer(
|
||||
4 * sourceCtor.BYTES_PER_ELEMENT,
|
||||
8 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
const fixedLength = new sourceCtor(rab, 0, 4);
|
||||
const fixedLengthWithOffset = new sourceCtor(
|
||||
rab, 2 * sourceCtor.BYTES_PER_ELEMENT, 2);
|
||||
const lengthTracking = new sourceCtor(rab, 0);
|
||||
const lengthTrackingWithOffset = new sourceCtor(
|
||||
rab, 2 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
|
||||
assertThrows(() => { new targetCtor(fixedLength); }, TypeError);
|
||||
assertThrows(() => { new targetCtor(fixedLengthWithOffset); }, TypeError);
|
||||
assertThrows(() => { new targetCtor(lengthTracking); }, TypeError);
|
||||
assertThrows(() => { new targetCtor(lengthTrackingWithOffset); },
|
||||
TypeError);
|
||||
});
|
||||
})();
|
||||
|
||||
(function TypedArrayLengthWhenResizedOutOfBounds1() {
|
||||
@ -7646,3 +7664,102 @@ SortCallbackGrows(ArraySortHelper);
|
||||
ToNumbers(func.apply(null, lengthTrackingWithOffset)));
|
||||
}
|
||||
})();
|
||||
|
||||
(function TypedArrayFrom() {
|
||||
AllBigIntMatchedCtorCombinations((targetCtor, sourceCtor) => {
|
||||
const rab = CreateResizableArrayBuffer(
|
||||
4 * sourceCtor.BYTES_PER_ELEMENT,
|
||||
8 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
const fixedLength = new sourceCtor(rab, 0, 4);
|
||||
const fixedLengthWithOffset = new sourceCtor(
|
||||
rab, 2 * sourceCtor.BYTES_PER_ELEMENT, 2);
|
||||
const lengthTracking = new sourceCtor(rab, 0);
|
||||
const lengthTrackingWithOffset = new sourceCtor(
|
||||
rab, 2 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
|
||||
// Write some data into the array.
|
||||
const taFull = new sourceCtor(rab);
|
||||
for (let i = 0; i < 4; ++i) {
|
||||
WriteToTypedArray(taFull, i, i + 1);
|
||||
}
|
||||
|
||||
// Orig. array: [1, 2, 3, 4]
|
||||
// [1, 2, 3, 4] << fixedLength
|
||||
// [3, 4] << fixedLengthWithOffset
|
||||
// [1, 2, 3, 4, ...] << lengthTracking
|
||||
// [3, 4, ...] << lengthTrackingWithOffset
|
||||
|
||||
assertEquals([1, 2, 3, 4], ToNumbers(targetCtor.from(fixedLength)));
|
||||
assertEquals([3, 4], ToNumbers(targetCtor.from(fixedLengthWithOffset)));
|
||||
assertEquals([1, 2, 3, 4], ToNumbers(targetCtor.from(lengthTracking)));
|
||||
assertEquals([3, 4], ToNumbers(targetCtor.from(lengthTrackingWithOffset)));
|
||||
|
||||
// Shrink so that fixed length TAs go out of bounds.
|
||||
rab.resize(3 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
|
||||
// Orig. array: [1, 2, 3]
|
||||
// [1, 2, 3, ...] << lengthTracking
|
||||
// [3, ...] << lengthTrackingWithOffset
|
||||
|
||||
assertThrows(() => { targetCtor.from(fixedLength); }, TypeError);
|
||||
assertThrows(() => { targetCtor.from(fixedLengthWithOffset); }, TypeError);
|
||||
assertEquals([1, 2, 3], ToNumbers(targetCtor.from(lengthTracking)));
|
||||
assertEquals([3], ToNumbers(targetCtor.from(lengthTrackingWithOffset)));
|
||||
|
||||
// Shrink so that the TAs with offset go out of bounds.
|
||||
rab.resize(1 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
|
||||
assertThrows(() => { targetCtor.from(fixedLength); }, TypeError);
|
||||
assertThrows(() => { targetCtor.from(fixedLengthWithOffset); }, TypeError);
|
||||
assertEquals([1], ToNumbers(targetCtor.from(lengthTracking)));
|
||||
assertThrows(() => { targetCtor.from(lengthTrackingWithOffset); },
|
||||
TypeError);
|
||||
|
||||
// Shrink to zero.
|
||||
rab.resize(0);
|
||||
|
||||
assertThrows(() => { targetCtor.from(fixedLength); }, TypeError);
|
||||
assertThrows(() => { targetCtor.from(fixedLengthWithOffset); }, TypeError);
|
||||
assertEquals([], ToNumbers(targetCtor.from(lengthTracking)));
|
||||
assertThrows(() => { targetCtor.from(lengthTrackingWithOffset); },
|
||||
TypeError);
|
||||
|
||||
// Grow so that all TAs are back in-bounds.
|
||||
rab.resize(6 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
|
||||
for (let i = 0; i < 6; ++i) {
|
||||
WriteToTypedArray(taFull, i, i + 1);
|
||||
}
|
||||
|
||||
// Orig. array: [1, 2, 3, 4, 5, 6]
|
||||
// [1, 2, 3, 4] << fixedLength
|
||||
// [3, 4] << fixedLengthWithOffset
|
||||
// [1, 2, 3, 4, 5, 6, ...] << lengthTracking
|
||||
// [3, 4, 5, 6, ...] << lengthTrackingWithOffset
|
||||
|
||||
assertEquals([1, 2, 3, 4], ToNumbers(targetCtor.from(fixedLength)));
|
||||
assertEquals([3, 4], ToNumbers(targetCtor.from(fixedLengthWithOffset)));
|
||||
assertEquals([1, 2, 3, 4, 5, 6],
|
||||
ToNumbers(targetCtor.from(lengthTracking)));
|
||||
assertEquals([3, 4, 5, 6],
|
||||
ToNumbers(targetCtor.from(lengthTrackingWithOffset)));
|
||||
});
|
||||
|
||||
AllBigIntUnmatchedCtorCombinations((targetCtor, sourceCtor) => {
|
||||
const rab = CreateResizableArrayBuffer(
|
||||
4 * sourceCtor.BYTES_PER_ELEMENT,
|
||||
8 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
const fixedLength = new sourceCtor(rab, 0, 4);
|
||||
const fixedLengthWithOffset = new sourceCtor(
|
||||
rab, 2 * sourceCtor.BYTES_PER_ELEMENT, 2);
|
||||
const lengthTracking = new sourceCtor(rab, 0);
|
||||
const lengthTrackingWithOffset = new sourceCtor(
|
||||
rab, 2 * sourceCtor.BYTES_PER_ELEMENT);
|
||||
|
||||
assertThrows(() => { targetCtor.from(fixedLength); }, TypeError);
|
||||
assertThrows(() => { targetCtor.from(fixedLengthWithOffset); }, TypeError);
|
||||
assertThrows(() => { targetCtor.from(lengthTracking); }, TypeError);
|
||||
assertThrows(() => { targetCtor.from(lengthTrackingWithOffset); },
|
||||
TypeError);
|
||||
});
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user