@@ -64,6 +64,17 @@ static const uint32_t kLatestVersion = 15;
64
64
static_assert (kLatestVersion == v8::CurrentValueSerializerFormatVersion(),
65
65
" Exported format version must match latest version." );
66
66
67
+ namespace {
68
+ // For serializing JSArrayBufferView flags. Instead of serializing /
69
+ // deserializing the flags directly, we serialize them bit by bit. This is for
70
+ // ensuring backwards compatilibity in the case where the representation
71
+ // changes. Note that the ValueSerializer data can be stored on disk.
72
+ using JSArrayBufferViewIsLengthTracking = base::BitField<bool , 0 , 1 >;
73
+ using JSArrayBufferViewIsBackedByRab =
74
+ JSArrayBufferViewIsLengthTracking::Next<bool , 1 >;
75
+
76
+ } // namespace
77
+
67
78
template <typename T>
68
79
static size_t BytesNeededForVarint (T value) {
69
80
static_assert (std::is_integral<T>::value && std::is_unsigned<T>::value,
@@ -922,6 +933,8 @@ Maybe<bool> ValueSerializer::WriteJSArrayBuffer(
922
933
if (byte_length > std::numeric_limits<uint32_t >::max ()) {
923
934
return ThrowDataCloneError (MessageTemplate::kDataCloneError , array_buffer);
924
935
}
936
+ // TODO(v8:11111): Support RAB / GSAB. The wire version will need to be
937
+ // bumped.
925
938
WriteTag (SerializationTag::kArrayBuffer );
926
939
WriteVarint<uint32_t >(byte_length);
927
940
WriteRawBytes (array_buffer->backing_store (), byte_length);
@@ -950,7 +963,10 @@ Maybe<bool> ValueSerializer::WriteJSArrayBufferView(JSArrayBufferView view) {
950
963
WriteVarint (static_cast <uint8_t >(tag));
951
964
WriteVarint (static_cast <uint32_t >(view.byte_offset ()));
952
965
WriteVarint (static_cast <uint32_t >(view.byte_length ()));
953
- WriteVarint (static_cast <uint32_t >(view.bit_field ()));
966
+ uint32_t flags =
967
+ JSArrayBufferViewIsLengthTracking::encode (view.is_length_tracking ()) |
968
+ JSArrayBufferViewIsBackedByRab::encode (view.is_backed_by_rab ());
969
+ WriteVarint (flags);
954
970
return ThrowIfOutOfMemory ();
955
971
}
956
972
@@ -1979,7 +1995,7 @@ MaybeHandle<JSArrayBuffer> ValueDeserializer::ReadTransferredJSArrayBuffer() {
1979
1995
1980
1996
MaybeHandle<JSArrayBufferView> ValueDeserializer::ReadJSArrayBufferView (
1981
1997
Handle <JSArrayBuffer> buffer) {
1982
- uint32_t buffer_byte_length = static_cast <uint32_t >(buffer->byte_length ());
1998
+ uint32_t buffer_byte_length = static_cast <uint32_t >(buffer->GetByteLength ());
1983
1999
uint8_t tag = 0 ;
1984
2000
uint32_t byte_offset = 0 ;
1985
2001
uint32_t byte_length = 0 ;
@@ -2004,7 +2020,9 @@ MaybeHandle<JSArrayBufferView> ValueDeserializer::ReadJSArrayBufferView(
2004
2020
Handle <JSDataView> data_view =
2005
2021
isolate_->factory ()->NewJSDataView (buffer, byte_offset, byte_length);
2006
2022
AddObjectWithID (id, data_view);
2007
- data_view->set_bit_field (flags);
2023
+ if (!ValidateAndSetJSArrayBufferViewFlags (*data_view, *buffer, flags)) {
2024
+ return MaybeHandle<JSArrayBufferView>();
2025
+ }
2008
2026
return data_view;
2009
2027
}
2010
2028
#define TYPED_ARRAY_CASE (Type, type, TYPE, ctype ) \
@@ -2021,11 +2039,39 @@ MaybeHandle<JSArrayBufferView> ValueDeserializer::ReadJSArrayBufferView(
2021
2039
}
2022
2040
Handle <JSTypedArray> typed_array = isolate_->factory ()->NewJSTypedArray (
2023
2041
external_array_type, buffer, byte_offset, byte_length / element_size);
2024
- typed_array->set_bit_field (flags);
2042
+ if (!ValidateAndSetJSArrayBufferViewFlags (*typed_array, *buffer, flags)) {
2043
+ return MaybeHandle<JSArrayBufferView>();
2044
+ }
2025
2045
AddObjectWithID (id, typed_array);
2026
2046
return typed_array;
2027
2047
}
2028
2048
2049
+ bool ValueDeserializer::ValidateAndSetJSArrayBufferViewFlags (
2050
+ JSArrayBufferView view, JSArrayBuffer buffer, uint32_t serialized_flags) {
2051
+ bool is_length_tracking =
2052
+ JSArrayBufferViewIsLengthTracking::decode (serialized_flags);
2053
+ bool is_backed_by_rab =
2054
+ JSArrayBufferViewIsBackedByRab::decode (serialized_flags);
2055
+
2056
+ // TODO(marja): When the version number is bumped the next time, check that
2057
+ // serialized_flags doesn't contain spurious 1-bits.
2058
+
2059
+ if (is_backed_by_rab || is_length_tracking) {
2060
+ if (!FLAG_harmony_rab_gsab) {
2061
+ return false ;
2062
+ }
2063
+ if (!buffer.is_resizable ()) {
2064
+ return false ;
2065
+ }
2066
+ if (is_backed_by_rab && buffer.is_shared ()) {
2067
+ return false ;
2068
+ }
2069
+ }
2070
+ view.set_is_length_tracking (is_length_tracking);
2071
+ view.set_is_backed_by_rab (is_backed_by_rab);
2072
+ return true ;
2073
+ }
2074
+
2029
2075
MaybeHandle<Object> ValueDeserializer::ReadJSError () {
2030
2076
uint32_t id = next_id_++;
2031
2077
0 commit comments