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

[rab / gsab] Add tests for the recent DataView bugs

In addition, make the code less confusing and more future proof:
- initialize the JSArrayBufferView bit_field to 0 (not only zeroing the
relevant bits)
- serialize it as uint32, since it's an uint32.

Bug: v8:11111
Change-Id: Iffbbb27cc8c821587f992668bfbcf2448a776f15
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3300132Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarShu-yu Guo <syg@chromium.org>
Reviewed-by: 's avatarDominik Inführ <dinfuehr@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78075}
parent 6cbead8f
......@@ -105,6 +105,7 @@ BUILTIN(DataViewConstructor) {
// TODO(v8:10391, saelo): Handle external pointers in EmbedderDataSlot
data_view->SetEmbedderField(i, Smi::zero());
}
data_view->set_bit_field(0);
data_view->set_is_backed_by_rab(array_buffer->is_resizable() &&
!array_buffer->is_shared());
data_view->set_is_length_tracking(length_tracking);
......
......@@ -335,6 +335,7 @@ transitioning macro TypedArrayCreateByLength(implicit context: Context)(
// ValidateTypedArray currently returns the array, not the ViewBuffer.
const newTypedArray: JSTypedArray =
ValidateTypedArray(context, newTypedArrayObj, methodName);
// TODO(v8:11111): bit_field should be initialized to 0.
newTypedArray.bit_field.is_length_tracking = false;
newTypedArray.bit_field.is_backed_by_rab = false;
......
......@@ -2862,6 +2862,7 @@ Handle<JSArrayBufferView> Factory::NewJSArrayBufferView(
raw.set_buffer(*buffer, SKIP_WRITE_BARRIER);
raw.set_byte_offset(byte_offset);
raw.set_byte_length(byte_length);
raw.set_bit_field(0);
ZeroEmbedderFields(raw);
DCHECK_EQ(raw.GetEmbedderFieldCount(),
v8::ArrayBufferView::kEmbedderFieldCount);
......
......@@ -938,7 +938,7 @@ Maybe<bool> ValueSerializer::WriteJSArrayBufferView(JSArrayBufferView view) {
WriteVarint(static_cast<uint8_t>(tag));
WriteVarint(static_cast<uint32_t>(view.byte_offset()));
WriteVarint(static_cast<uint32_t>(view.byte_length()));
WriteVarint(static_cast<uint8_t>(view.bit_field()));
WriteVarint(static_cast<uint32_t>(view.bit_field()));
return ThrowIfOutOfMemory();
}
......@@ -1863,11 +1863,11 @@ MaybeHandle<JSArrayBufferView> ValueDeserializer::ReadJSArrayBufferView(
uint8_t tag = 0;
uint32_t byte_offset = 0;
uint32_t byte_length = 0;
uint8_t flags = 0;
uint32_t flags = 0;
if (!ReadVarint<uint8_t>().To(&tag) ||
!ReadVarint<uint32_t>().To(&byte_offset) ||
!ReadVarint<uint32_t>().To(&byte_length) ||
!ReadVarint<uint8_t>().To(&flags) || byte_offset > buffer_byte_length ||
!ReadVarint<uint32_t>().To(&flags) || byte_offset > buffer_byte_length ||
byte_length > buffer_byte_length - byte_offset) {
return MaybeHandle<JSArrayBufferView>();
}
......
......@@ -383,6 +383,12 @@ void TypedArrayTestHelper(i::ExternalArrayType array_type, int64_t low,
ObjectWithExternalArrayTestHelper<ElementType>(env.local(), ta, kElementCount,
array_type, low, high);
// TODO(v8:11111): Use API functions for testing these, once they're exposed
// via the API.
i::Handle<i::JSTypedArray> i_ta = v8::Utils::OpenHandle(*ta);
CHECK(!i_ta->is_length_tracking());
CHECK(!i_ta->is_backed_by_rab());
}
} // namespace
......@@ -445,6 +451,12 @@ THREADED_TEST(DataView) {
CHECK_EQ(2u, dv->ByteOffset());
CHECK_EQ(kSize, static_cast<int>(dv->ByteLength()));
CHECK(ab->Equals(env.local(), dv->Buffer()).FromJust());
// TODO(v8:11111): Use API functions for testing these, once they're exposed
// via the API.
i::Handle<i::JSDataView> i_dv = v8::Utils::OpenHandle(*dv);
CHECK(!i_dv->is_length_tracking());
CHECK(!i_dv->is_backed_by_rab());
}
THREADED_TEST(SharedUint8Array) {
......@@ -516,6 +528,12 @@ THREADED_TEST(SharedDataView) {
CHECK_EQ(2u, dv->ByteOffset());
CHECK_EQ(kSize, static_cast<int>(dv->ByteLength()));
CHECK(ab->Equals(env.local(), dv->Buffer()).FromJust());
// TODO(v8:11111): Use API functions for testing these, once they're exposed
// via the API.
i::Handle<i::JSDataView> i_dv = v8::Utils::OpenHandle(*dv);
CHECK(!i_dv->is_length_tracking());
CHECK(!i_dv->is_backed_by_rab());
}
#define IS_ARRAY_BUFFER_VIEW_TEST(View) \
......
......@@ -19,6 +19,7 @@
#include "src/api/api-inl.h"
#include "src/base/build_config.h"
#include "src/objects/backing-store.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/objects-inl.h"
#include "test/unittests/test-utils.h"
#include "testing/gmock/include/gmock/gmock.h"
......@@ -1987,6 +1988,11 @@ TEST_F(ValueSerializerTest, RoundTripDataView) {
EXPECT_EQ(2u, DataView::Cast(*value)->ByteLength());
EXPECT_EQ(4u, DataView::Cast(*value)->Buffer()->ByteLength());
ExpectScriptTrue("Object.getPrototypeOf(result) === DataView.prototype");
// TODO(v8:11111): Use API functions for testing these, once they're exposed
// via the API.
i::Handle<i::JSDataView> i_dv = v8::Utils::OpenHandle(DataView::Cast(*value));
EXPECT_EQ(false, i_dv->is_length_tracking());
EXPECT_EQ(false, i_dv->is_backed_by_rab());
}
TEST_F(ValueSerializerTest, DecodeDataView) {
......
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