summaryrefslogtreecommitdiff
path: root/deps/v8/test/unittests/objects/value-serializer-unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/unittests/objects/value-serializer-unittest.cc')
-rw-r--r--deps/v8/test/unittests/objects/value-serializer-unittest.cc172
1 files changed, 169 insertions, 3 deletions
diff --git a/deps/v8/test/unittests/objects/value-serializer-unittest.cc b/deps/v8/test/unittests/objects/value-serializer-unittest.cc
index 8a36f6dbb3..a2f6461ab2 100644
--- a/deps/v8/test/unittests/objects/value-serializer-unittest.cc
+++ b/deps/v8/test/unittests/objects/value-serializer-unittest.cc
@@ -21,7 +21,9 @@
#include "src/base/build_config.h"
#include "src/objects/backing-store.h"
#include "src/objects/js-array-buffer-inl.h"
+#include "src/objects/js-array-buffer.h"
#include "src/objects/objects-inl.h"
+#include "test/common/flag-utils.h"
#include "test/unittests/test-utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -1398,7 +1400,6 @@ TEST_F(ValueSerializerTest, RoundTripDate) {
}
TEST_F(ValueSerializerTest, DecodeDate) {
- Local<Value> value;
#if defined(V8_TARGET_LITTLE_ENDIAN)
DecodeTestFutureVersions(
{0xFF, 0x09, 0x3F, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x80, 0x84, 0x2E,
@@ -1884,11 +1885,20 @@ TEST_F(ValueSerializerTest, RoundTripArrayBuffer) {
ASSERT_TRUE(value->IsArrayBuffer());
EXPECT_EQ(0u, ArrayBuffer::Cast(*value)->ByteLength());
ExpectScriptTrue("Object.getPrototypeOf(result) === ArrayBuffer.prototype");
+ // TODO(v8:11111): Use API functions for testing max_byte_length and resizable
+ // once they're exposed via the API.
+ i::Handle<i::JSArrayBuffer> array_buffer =
+ Utils::OpenHandle(ArrayBuffer::Cast(*value));
+ EXPECT_EQ(0u, array_buffer->max_byte_length());
+ EXPECT_EQ(false, array_buffer->is_resizable_by_js());
value = RoundTripTest("new Uint8Array([0, 128, 255]).buffer");
ASSERT_TRUE(value->IsArrayBuffer());
EXPECT_EQ(3u, ArrayBuffer::Cast(*value)->ByteLength());
ExpectScriptTrue("new Uint8Array(result).toString() === '0,128,255'");
+ array_buffer = Utils::OpenHandle(ArrayBuffer::Cast(*value));
+ EXPECT_EQ(3u, array_buffer->max_byte_length());
+ EXPECT_EQ(false, array_buffer->is_resizable_by_js());
value =
RoundTripTest("({ a: new ArrayBuffer(), get b() { return this.a; }})");
@@ -1896,6 +1906,21 @@ TEST_F(ValueSerializerTest, RoundTripArrayBuffer) {
ExpectScriptTrue("result.a === result.b");
}
+TEST_F(ValueSerializerTest, RoundTripResizableArrayBuffer) {
+ FLAG_SCOPE(harmony_rab_gsab);
+ Local<Value> value =
+ RoundTripTest("new ArrayBuffer(100, {maxByteLength: 200})");
+ ASSERT_TRUE(value->IsArrayBuffer());
+ EXPECT_EQ(100u, ArrayBuffer::Cast(*value)->ByteLength());
+
+ // TODO(v8:11111): Use API functions for testing max_byte_length and resizable
+ // once they're exposed via the API.
+ i::Handle<i::JSArrayBuffer> array_buffer =
+ Utils::OpenHandle(ArrayBuffer::Cast(*value));
+ EXPECT_EQ(200u, array_buffer->max_byte_length());
+ EXPECT_EQ(true, array_buffer->is_resizable_by_js());
+}
+
TEST_F(ValueSerializerTest, DecodeArrayBuffer) {
DecodeTestFutureVersions(
{0xFF, 0x09, 0x3F, 0x00, 0x42, 0x00}, [this](Local<Value> value) {
@@ -1927,6 +1952,13 @@ TEST_F(ValueSerializerTest, DecodeInvalidArrayBuffer) {
InvalidDecodeTest({0xFF, 0x09, 0x42, 0xFF, 0xFF, 0x00});
}
+TEST_F(ValueSerializerTest, DecodeInvalidResizableArrayBuffer) {
+ FLAG_SCOPE(harmony_rab_gsab);
+ // Enough bytes available after reading the length, but not anymore when
+ // reading the max byte length.
+ InvalidDecodeTest({0xFF, 0x09, 0x7E, 0x2, 0x10, 0x00});
+}
+
// An array buffer allocator that never has available memory.
class OOMArrayBufferAllocator : public ArrayBuffer::Allocator {
public:
@@ -2026,14 +2058,20 @@ TEST_F(ValueSerializerTestWithArrayBufferTransfer,
TEST_F(ValueSerializerTest, RoundTripTypedArray) {
// Check that the right type comes out the other side for every kind of typed
// array.
+ // TODO(v8:11111): Use API functions for testing is_length_tracking and
+ // is_backed_by_rab, once they're exposed via the API.
Local<Value> value;
+ i::Handle<i::JSTypedArray> i_ta;
#define TYPED_ARRAY_ROUND_TRIP_TEST(Type, type, TYPE, ctype) \
value = RoundTripTest("new " #Type "Array(2)"); \
ASSERT_TRUE(value->Is##Type##Array()); \
EXPECT_EQ(2u * sizeof(ctype), TypedArray::Cast(*value)->ByteLength()); \
EXPECT_EQ(2u, TypedArray::Cast(*value)->Length()); \
ExpectScriptTrue("Object.getPrototypeOf(result) === " #Type \
- "Array.prototype");
+ "Array.prototype"); \
+ i_ta = v8::Utils::OpenHandle(TypedArray::Cast(*value)); \
+ EXPECT_EQ(false, i_ta->is_length_tracking()); \
+ EXPECT_EQ(false, i_ta->is_backed_by_rab());
TYPED_ARRAYS(TYPED_ARRAY_ROUND_TRIP_TEST)
#undef TYPED_ARRAY_ROUND_TRIP_TEST
@@ -2066,6 +2104,56 @@ TEST_F(ValueSerializerTest, RoundTripTypedArray) {
ExpectScriptTrue("result.f32.length === 5");
}
+TEST_F(ValueSerializerTest, RoundTripRabBackedLengthTrackingTypedArray) {
+ FLAG_SCOPE(harmony_rab_gsab);
+ // Check that the right type comes out the other side for every kind of typed
+ // array.
+ // TODO(v8:11111): Use API functions for testing is_length_tracking and
+ // is_backed_by_rab, once they're exposed via the API.
+ Local<Value> value;
+ i::Handle<i::JSTypedArray> i_ta;
+#define TYPED_ARRAY_ROUND_TRIP_TEST(Type, type, TYPE, ctype) \
+ value = RoundTripTest("new " #Type \
+ "Array(new ArrayBuffer(80, " \
+ "{maxByteLength: 160}))"); \
+ ASSERT_TRUE(value->Is##Type##Array()); \
+ EXPECT_EQ(80u, TypedArray::Cast(*value)->ByteLength()); \
+ EXPECT_EQ(80u / sizeof(ctype), TypedArray::Cast(*value)->Length()); \
+ ExpectScriptTrue("Object.getPrototypeOf(result) === " #Type \
+ "Array.prototype"); \
+ i_ta = v8::Utils::OpenHandle(TypedArray::Cast(*value)); \
+ EXPECT_EQ(true, i_ta->is_length_tracking()); \
+ EXPECT_EQ(true, i_ta->is_backed_by_rab());
+
+ TYPED_ARRAYS(TYPED_ARRAY_ROUND_TRIP_TEST)
+#undef TYPED_ARRAY_ROUND_TRIP_TEST
+}
+
+TEST_F(ValueSerializerTest, RoundTripRabBackedNonLengthTrackingTypedArray) {
+ FLAG_SCOPE(harmony_rab_gsab);
+ // Check that the right type comes out the other side for every kind of typed
+ // array.
+ // TODO(v8:11111): Use API functions for testing is_length_tracking and
+ // is_backed_by_rab, once they're exposed via the API.
+ Local<Value> value;
+ i::Handle<i::JSTypedArray> i_ta;
+#define TYPED_ARRAY_ROUND_TRIP_TEST(Type, type, TYPE, ctype) \
+ value = RoundTripTest("new " #Type \
+ "Array(new ArrayBuffer(80, " \
+ "{maxByteLength: 160}), 8, 4)"); \
+ ASSERT_TRUE(value->Is##Type##Array()); \
+ EXPECT_EQ(4u * sizeof(ctype), TypedArray::Cast(*value)->ByteLength()); \
+ EXPECT_EQ(4u, TypedArray::Cast(*value)->Length()); \
+ ExpectScriptTrue("Object.getPrototypeOf(result) === " #Type \
+ "Array.prototype"); \
+ i_ta = v8::Utils::OpenHandle(TypedArray::Cast(*value)); \
+ EXPECT_EQ(false, i_ta->is_length_tracking()); \
+ EXPECT_EQ(true, i_ta->is_backed_by_rab());
+
+ TYPED_ARRAYS(TYPED_ARRAY_ROUND_TRIP_TEST)
+#undef TYPED_ARRAY_ROUND_TRIP_TEST
+}
+
TEST_F(ValueSerializerTest, DecodeTypedArray) {
// Check that the right type comes out the other side for every kind of typed
// array (version 14 and above).
@@ -2397,7 +2485,8 @@ TEST_F(ValueSerializerTest, RoundTripDataView) {
// TODO(v8:11111): Use API functions for testing is_length_tracking and
// is_backed_by_rab, once they're exposed
// via the API.
- i::Handle<i::JSDataView> i_dv = v8::Utils::OpenHandle(DataView::Cast(*value));
+ i::Handle<i::JSDataViewOrRabGsabDataView> 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());
}
@@ -2416,6 +2505,42 @@ TEST_F(ValueSerializerTest, DecodeDataView) {
});
}
+TEST_F(ValueSerializerTest, RoundTripRabBackedDataView) {
+ FLAG_SCOPE(harmony_rab_gsab);
+
+ Local<Value> value = RoundTripTest(
+ "new DataView(new ArrayBuffer(4, {maxByteLength: 8}), 1, 2)");
+ ASSERT_TRUE(value->IsDataView());
+ EXPECT_EQ(1u, DataView::Cast(*value)->ByteOffset());
+ 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 is_length_tracking and
+ // is_backed_by_rab, once they're exposed via the API.
+ i::Handle<i::JSDataViewOrRabGsabDataView> i_dv =
+ v8::Utils::OpenHandle(DataView::Cast(*value));
+ EXPECT_EQ(false, i_dv->is_length_tracking());
+ EXPECT_EQ(true, i_dv->is_backed_by_rab());
+}
+
+TEST_F(ValueSerializerTest, RoundTripRabBackedLengthTrackingDataView) {
+ FLAG_SCOPE(harmony_rab_gsab);
+
+ Local<Value> value =
+ RoundTripTest("new DataView(new ArrayBuffer(4, {maxByteLength: 8}), 1)");
+ ASSERT_TRUE(value->IsDataView());
+ EXPECT_EQ(1u, DataView::Cast(*value)->ByteOffset());
+ EXPECT_EQ(3u, 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 is_length_tracking and
+ // is_backed_by_rab, once they're exposed via the API.
+ i::Handle<i::JSDataViewOrRabGsabDataView> i_dv =
+ v8::Utils::OpenHandle(DataView::Cast(*value));
+ EXPECT_EQ(true, i_dv->is_length_tracking());
+ EXPECT_EQ(true, i_dv->is_backed_by_rab());
+}
+
TEST_F(ValueSerializerTest, DecodeDataViewBackwardsCompatibility) {
DecodeTestUpToVersion(
13,
@@ -2633,6 +2758,47 @@ TEST_F(ValueSerializerTestWithSharedArrayBufferClone,
ExpectScriptTrue(
"new Uint8Array(result.buffer, 0, 4).toString() === '0,1,128,255'");
}
+
+TEST_F(ValueSerializerTestWithSharedArrayBufferClone,
+ RoundTripWebAssemblyMemory_WithPreviousReference) {
+ // This is a regression test for crbug.com/1421524.
+ // It ensures that WasmMemoryObject can deserialize even if its underlying
+ // buffer was already encountered, and so will be encoded with an object
+ // backreference.
+ std::vector<uint8_t> data = {0x00, 0x01, 0x80, 0xFF};
+ data.resize(65536);
+ InitializeData(data, true);
+
+ EXPECT_CALL(serializer_delegate_,
+ GetSharedArrayBufferId(isolate(), input_buffer()))
+ .WillRepeatedly(Return(Just(0U)));
+ EXPECT_CALL(deserializer_delegate_, GetSharedArrayBufferFromId(isolate(), 0U))
+ .WillRepeatedly(Return(output_buffer()));
+
+ Local<Value> input;
+ {
+ Context::Scope scope(serialization_context());
+ const int32_t kMaxPages = 1;
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate());
+ i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*input_buffer());
+ i::Handle<i::WasmMemoryObject> wasm_memory =
+ i::WasmMemoryObject::New(i_isolate, buffer, kMaxPages)
+ .ToHandleChecked();
+ i::Handle<i::FixedArray> fixed_array =
+ i_isolate->factory()->NewFixedArray(2);
+ fixed_array->set(0, *buffer);
+ fixed_array->set(1, *wasm_memory);
+ input = Utils::ToLocal(i_isolate->factory()->NewJSArrayWithElements(
+ fixed_array, i::PACKED_ELEMENTS, 2));
+ }
+ RoundTripTest(input);
+ ExpectScriptTrue("result[0] instanceof SharedArrayBuffer");
+ ExpectScriptTrue("result[1] instanceof WebAssembly.Memory");
+ ExpectScriptTrue("result[0] === result[1].buffer");
+ ExpectScriptTrue("result[0].byteLength === 65536");
+ ExpectScriptTrue(
+ "new Uint8Array(result[0], 0, 4).toString() === '0,1,128,255'");
+}
#endif // V8_ENABLE_WEBASSEMBLY
TEST_F(ValueSerializerTest, UnsupportedHostObject) {