| Index: src/value-serializer.cc
|
| diff --git a/src/value-serializer.cc b/src/value-serializer.cc
|
| index 9dfaa4a857805abbf42a57856b86248b033a10d9..51fdf2212b4f2a5420fd22b7f98a9a8d4e7401cc 100644
|
| --- a/src/value-serializer.cc
|
| +++ b/src/value-serializer.cc
|
| @@ -25,7 +25,8 @@ namespace internal {
|
|
|
| // Version 9: (imported from Blink)
|
| // Version 10: one-byte (Latin-1) strings
|
| -static const uint32_t kLatestVersion = 10;
|
| +// Version 11: properly separate undefined from the hole in arrays
|
| +static const uint32_t kLatestVersion = 11;
|
|
|
| static const int kPretenureThreshold = 100 * KB;
|
|
|
| @@ -49,6 +50,7 @@ enum class SerializationTag : uint8_t {
|
| // refTableSize:uint32_t (previously used for sanity checks; safe to ignore)
|
| kVerifyObjectCount = '?',
|
| // Oddballs (no data).
|
| + kTheHole = '-',
|
| kUndefined = '_',
|
| kNull = '0',
|
| kTrue = 'T',
|
| @@ -538,10 +540,6 @@ Maybe<bool> ValueSerializer::WriteJSArray(Handle<JSArray> array) {
|
|
|
| if (should_serialize_densely) {
|
| DCHECK_LE(length, static_cast<uint32_t>(FixedArray::kMaxLength));
|
| -
|
| - // TODO(jbroman): Distinguish between undefined and a hole (this can happen
|
| - // if serializing one of the elements deletes another). This requires wire
|
| - // format changes.
|
| WriteTag(SerializationTag::kBeginDenseJSArray);
|
| WriteVarint<uint32_t>(length);
|
| uint32_t i = 0;
|
| @@ -589,6 +587,13 @@ Maybe<bool> ValueSerializer::WriteJSArray(Handle<JSArray> array) {
|
| // with.
|
| Handle<Object> element;
|
| LookupIterator it(isolate_, array, i, array, LookupIterator::OWN);
|
| + if (!it.IsFound()) {
|
| + // This can happen in the case where an array that was originally dense
|
| + // became sparse during serialization. It's too late to switch to the
|
| + // sparse format, but we can mark the elements as absent.
|
| + WriteTag(SerializationTag::kTheHole);
|
| + continue;
|
| + }
|
| if (!Object::GetProperty(&it).ToHandle(&element) ||
|
| !WriteObject(element).FromMaybe(false)) {
|
| return Nothing<bool>();
|
| @@ -1320,10 +1325,20 @@ MaybeHandle<JSArray> ValueDeserializer::ReadDenseJSArray() {
|
|
|
| Handle<FixedArray> elements(FixedArray::cast(array->elements()), isolate_);
|
| for (uint32_t i = 0; i < length; i++) {
|
| + SerializationTag tag;
|
| + if (PeekTag().To(&tag) && tag == SerializationTag::kTheHole) {
|
| + ConsumeTag(SerializationTag::kTheHole);
|
| + continue;
|
| + }
|
| +
|
| Handle<Object> element;
|
| if (!ReadObject().ToHandle(&element)) return MaybeHandle<JSArray>();
|
| - // TODO(jbroman): Distinguish between undefined and a hole.
|
| - if (element->IsUndefined(isolate_)) continue;
|
| +
|
| + // Serialization versions less than 11 encode the hole the same as
|
| + // undefined. For consistency with previous behavior, store these as the
|
| + // hole. Past version 11, undefined means undefined.
|
| + if (version_ < 11 && element->IsUndefined(isolate_)) continue;
|
| +
|
| elements->set(i, *element);
|
| }
|
|
|
|
|