| Index: src/value-serializer.cc
|
| diff --git a/src/value-serializer.cc b/src/value-serializer.cc
|
| index 156ef9227c1ef9d83cbe6afa20cf8034d41c9582..ad7492a2a60f32c03ca30b4808fb8954c3f95fb1 100644
|
| --- a/src/value-serializer.cc
|
| +++ b/src/value-serializer.cc
|
| @@ -340,6 +340,12 @@ Maybe<SerializationTag> ValueDeserializer::PeekTag() const {
|
| return Just(tag);
|
| }
|
|
|
| +void ValueDeserializer::ConsumeTag(SerializationTag peeked_tag) {
|
| + SerializationTag actual_tag = ReadTag().ToChecked();
|
| + DCHECK(actual_tag == peeked_tag);
|
| + USE(actual_tag);
|
| +}
|
| +
|
| Maybe<SerializationTag> ValueDeserializer::ReadTag() {
|
| SerializationTag tag;
|
| do {
|
| @@ -517,9 +523,7 @@ Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties(
|
| SerializationTag tag;
|
| if (!PeekTag().To(&tag)) return Nothing<uint32_t>();
|
| if (tag == end_tag) {
|
| - SerializationTag consumed_tag = ReadTag().ToChecked();
|
| - USE(consumed_tag);
|
| - DCHECK(tag == consumed_tag);
|
| + ConsumeTag(end_tag);
|
| return Just(num_properties);
|
| }
|
|
|
| @@ -569,5 +573,77 @@ void ValueDeserializer::AddObjectWithID(uint32_t id,
|
| }
|
| }
|
|
|
| +static MaybeHandle<JSObject> CreateJSObjectFromKeyValuePairs(
|
| + Isolate* isolate, Handle<Object>* data, uint32_t num_properties) {
|
| + Handle<JSObject> object =
|
| + isolate->factory()->NewJSObject(isolate->object_function());
|
| + for (unsigned i = 0; i < 2 * num_properties; i += 2) {
|
| + Handle<Object> key = data[i];
|
| + Handle<Object> value = data[i + 1];
|
| + bool success;
|
| + LookupIterator it = LookupIterator::PropertyOrElement(
|
| + isolate, object, key, &success, LookupIterator::OWN);
|
| + if (!success ||
|
| + JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, NONE)
|
| + .is_null()) {
|
| + return MaybeHandle<JSObject>();
|
| + }
|
| + }
|
| + return object;
|
| +}
|
| +
|
| +MaybeHandle<Object>
|
| +ValueDeserializer::ReadObjectUsingEntireBufferForLegacyFormat() {
|
| + if (version_ > 0) return MaybeHandle<Object>();
|
| +
|
| + HandleScope scope(isolate_);
|
| + std::vector<Handle<Object>> stack;
|
| + while (position_ < end_) {
|
| + SerializationTag tag;
|
| + if (!PeekTag().To(&tag)) break;
|
| +
|
| + Handle<Object> new_object;
|
| + switch (tag) {
|
| + case SerializationTag::kEndJSObject: {
|
| + ConsumeTag(SerializationTag::kEndJSObject);
|
| +
|
| + // JS Object: Read the last 2*n values from the stack and use them as
|
| + // key-value pairs.
|
| + uint32_t num_properties;
|
| + if (!ReadVarint<uint32_t>().To(&num_properties) ||
|
| + stack.size() / 2 < num_properties) {
|
| + return MaybeHandle<Object>();
|
| + }
|
| +
|
| + size_t begin_properties = stack.size() - 2 * num_properties;
|
| + Handle<Object>* data =
|
| + num_properties ? &stack[begin_properties] : nullptr;
|
| + if (!CreateJSObjectFromKeyValuePairs(isolate_, data, num_properties)
|
| + .ToHandle(&new_object)) {
|
| + return MaybeHandle<Object>();
|
| + }
|
| +
|
| + stack.resize(begin_properties);
|
| + break;
|
| + }
|
| + default:
|
| + if (!ReadObject().ToHandle(&new_object)) return MaybeHandle<Object>();
|
| + break;
|
| + }
|
| + stack.push_back(new_object);
|
| + }
|
| +
|
| +// Nothing remains but padding.
|
| +#ifdef DEBUG
|
| + while (position_ < end_) {
|
| + DCHECK(*position_++ == static_cast<uint8_t>(SerializationTag::kPadding));
|
| + }
|
| +#endif
|
| + position_ = end_;
|
| +
|
| + if (stack.size() != 1) return MaybeHandle<Object>();
|
| + return scope.CloseAndEscape(stack[0]);
|
| +}
|
| +
|
| } // namespace internal
|
| } // namespace v8
|
|
|