Commit 140cd812 authored by Marja Hölttä's avatar Marja Hölttä Committed by V8 LUCI CQ

[rab/gsab] Update TypedArrayPrototypeByteOffset

This CL assumes https://github.com/tc39/proposal-resizablearraybuffer/issues/68
is indeed a spec bug.

Bug: v8:11111
Change-Id: I8d24f0d07f7ab40ba01b8c422868ad189d6f7e5a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3060478
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76001}
parent faf85529
......@@ -154,13 +154,16 @@ TF_BUILTIN(TypedArrayPrototypeByteOffset, TypedArrayBuiltinsAssembler) {
// Check if the {receiver} is actually a JSTypedArray.
ThrowIfNotInstanceType(context, receiver, JS_TYPED_ARRAY_TYPE, kMethodName);
// Default to zero if the {receiver}s buffer was detached.
TNode<JSArrayBuffer> receiver_buffer =
LoadJSArrayBufferViewBuffer(CAST(receiver));
TNode<UintPtrT> byte_offset = Select<UintPtrT>(
IsDetachedBuffer(receiver_buffer), [=] { return UintPtrConstant(0); },
[=] { return LoadJSArrayBufferViewByteOffset(CAST(receiver)); });
Return(ChangeUintPtrToTagged(byte_offset));
// Default to zero if the {receiver}s buffer was detached / out of bounds.
Label detached_or_oob(this), not_detached_or_oob(this);
IsTypedArrayDetachedOrOutOfBounds(CAST(receiver), &detached_or_oob,
&not_detached_or_oob);
BIND(&detached_or_oob);
Return(ChangeUintPtrToTagged(UintPtrConstant(0)));
BIND(&not_detached_or_oob);
Return(
ChangeUintPtrToTagged(LoadJSArrayBufferViewByteOffset(CAST(receiver))));
}
// ES6 #sec-get-%typedarray%.prototype.length
......
......@@ -13926,6 +13926,45 @@ TNode<UintPtrT> CodeStubAssembler::LoadVariableLengthJSTypedArrayLength(
return result.value();
}
void CodeStubAssembler::IsTypedArrayDetachedOrOutOfBounds(
TNode<JSTypedArray> array, Label* detached_or_oob,
Label* not_detached_nor_oob) {
TNode<JSArrayBuffer> buffer = LoadJSArrayBufferViewBuffer(array);
GotoIf(IsDetachedBuffer(buffer), detached_or_oob);
GotoIfNot(IsVariableLengthTypedArray(array), not_detached_nor_oob);
GotoIf(IsSharedArrayBuffer(buffer), not_detached_nor_oob);
{
TNode<UintPtrT> buffer_byte_length = LoadJSArrayBufferByteLength(buffer);
TNode<UintPtrT> array_byte_offset = LoadJSArrayBufferViewByteOffset(array);
Label length_tracking(this), not_length_tracking(this);
Branch(IsLengthTrackingTypedArray(array), &length_tracking,
&not_length_tracking);
BIND(&length_tracking);
{
// The backing RAB might have been shrunk so that the start of the
// TypedArray is already out of bounds.
Branch(UintPtrLessThanOrEqual(array_byte_offset, buffer_byte_length),
not_detached_nor_oob, detached_or_oob);
}
BIND(&not_length_tracking);
{
// Check if the backing RAB has shrunk so that the buffer is out of
// bounds.
TNode<UintPtrT> array_byte_length =
LoadJSArrayBufferViewByteLength(array);
Branch(UintPtrGreaterThanOrEqual(
buffer_byte_length,
UintPtrAdd(array_byte_offset, array_byte_length)),
not_detached_nor_oob, detached_or_oob);
}
}
}
// ES #sec-integerindexedobjectbytelength
TNode<UintPtrT> CodeStubAssembler::LoadVariableLengthJSTypedArrayByteLength(
TNode<Context> context, TNode<JSTypedArray> array,
......
......@@ -3569,6 +3569,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<UintPtrT> LoadVariableLengthJSTypedArrayByteLength(
TNode<Context> context, TNode<JSTypedArray> array,
TNode<JSArrayBuffer> buffer);
void IsTypedArrayDetachedOrOutOfBounds(TNode<JSTypedArray> array,
Label* detached_or_oob,
Label* not_detached_nor_oob);
TNode<IntPtrT> RabGsabElementsKindToElementByteSize(
TNode<Int32T> elementsKind);
TNode<RawPtrT> LoadJSTypedArrayDataPtr(TNode<JSTypedArray> typed_array);
......
......@@ -148,6 +148,7 @@ function CreateResizableArrayBuffer(byteLength, maxByteLength) {
for (let [ta, length] of tas_and_lengths) {
assertEquals(length, ta.length);
assertEquals(length * ta.BYTES_PER_ELEMENT, ta.byteLength);
assertEquals(8, ta.byteOffset);
}
rab.resize(10);
......@@ -155,6 +156,7 @@ function CreateResizableArrayBuffer(byteLength, maxByteLength) {
for (let [ta, length] of tas_and_lengths) {
assertEquals(0, ta.length);
assertEquals(0, ta.byteLength);
assertEquals(0, ta.byteOffset);
}
// Resize the rab so that it just barely covers the needed 8 bytes.
......@@ -163,6 +165,7 @@ function CreateResizableArrayBuffer(byteLength, maxByteLength) {
for (let [ta, length] of tas_and_lengths) {
assertEquals(length, ta.length);
assertEquals(length * ta.BYTES_PER_ELEMENT, ta.byteLength);
assertEquals(8, ta.byteOffset);
}
rab.resize(40);
......@@ -170,6 +173,7 @@ function CreateResizableArrayBuffer(byteLength, maxByteLength) {
for (let [ta, length] of tas_and_lengths) {
assertEquals(length, ta.length);
assertEquals(length * ta.BYTES_PER_ELEMENT, ta.byteLength);
assertEquals(8, ta.byteOffset);
}
})();
......@@ -247,12 +251,14 @@ function CreateResizableArrayBuffer(byteLength, maxByteLength) {
for (let ta of tas) {
assertEquals((16 - offset) / ta.BYTES_PER_ELEMENT, ta.length);
assertEquals(16 - offset, ta.byteLength);
assertEquals(offset, ta.byteOffset);
}
rab.resize(40);
for (let ta of tas) {
assertEquals((40 - offset) / ta.BYTES_PER_ELEMENT, ta.length);
assertEquals(40 - offset, ta.byteLength);
assertEquals(offset, ta.byteOffset);
}
// Resize to a number which is not a multiple of all byte_lengths.
......@@ -261,6 +267,7 @@ function CreateResizableArrayBuffer(byteLength, maxByteLength) {
const expected_length = Math.floor((20 - offset)/ ta.BYTES_PER_ELEMENT);
assertEquals(expected_length, ta.length);
assertEquals(expected_length * ta.BYTES_PER_ELEMENT, ta.byteLength);
assertEquals(offset, ta.byteOffset);
}
// Resize so that all TypedArrays go out of bounds (because of the offset).
......@@ -269,6 +276,7 @@ function CreateResizableArrayBuffer(byteLength, maxByteLength) {
for (let ta of tas) {
assertEquals(0, ta.length);
assertEquals(0, ta.byteLength);
assertEquals(0, ta.byteOffset);
}
rab.resize(0);
......@@ -276,6 +284,7 @@ function CreateResizableArrayBuffer(byteLength, maxByteLength) {
for (let ta of tas) {
assertEquals(0, ta.length);
assertEquals(0, ta.byteLength);
assertEquals(0, ta.byteOffset);
}
rab.resize(8);
......@@ -283,6 +292,7 @@ function CreateResizableArrayBuffer(byteLength, maxByteLength) {
for (let ta of tas) {
assertEquals(0, ta.length);
assertEquals(0, ta.byteLength);
assertEquals(offset, ta.byteOffset);
}
// Resize so that the TypedArrays which have element size > 1 go out of bounds
......@@ -293,9 +303,11 @@ function CreateResizableArrayBuffer(byteLength, maxByteLength) {
if (ta.BYTES_PER_ELEMENT == 1) {
assertEquals(1, ta.length);
assertEquals(1, ta.byteLength);
assertEquals(offset, ta.byteOffset);
} else {
assertEquals(0, ta.length);
assertEquals(0, ta.byteLength);
assertEquals(offset, ta.byteOffset);
}
}
......@@ -304,6 +316,7 @@ function CreateResizableArrayBuffer(byteLength, maxByteLength) {
for (let ta of tas) {
assertEquals((40 - offset) / ta.BYTES_PER_ELEMENT, ta.length);
assertEquals(40 - offset, ta.byteLength);
assertEquals(offset, ta.byteOffset);
}
})();
......
......@@ -597,8 +597,6 @@
'built-ins/DataView/prototype/setUint8/resizable-buffer': [FAIL],
'built-ins/TypedArrayConstructors/ctors/typedarray-arg/out-of-bounds-when-species-retrieved-different-type': [FAIL],
'built-ins/TypedArrayConstructors/ctors/typedarray-arg/out-of-bounds-when-species-retrieved-same-type': [FAIL],
'built-ins/TypedArray/prototype/byteOffset/resizable-array-buffer-auto': [FAIL],
'built-ins/TypedArray/prototype/byteOffset/resizable-array-buffer-fixed': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=11544
'built-ins/Temporal/Calendar/prototype/fields/long-input': [FAIL],
......@@ -694,6 +692,9 @@
'built-ins/TypedArray/prototype/toLocaleString/return-abrupt-from-this-out-of-bounds': [SKIP],
'built-ins/TypedArray/prototype/values/return-abrupt-from-this-out-of-bounds': [FAIL],
# Pending update after https://github.com/tc39/proposal-resizablearraybuffer/issues/68
'built-ins/TypedArray/prototype/byteOffset/resizable-array-buffer-auto': [FAIL],
############################ SKIPPED TESTS #############################
# These tests take a looong time to run.
......
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