Chromium Code Reviews| Index: src/value-serializer.cc |
| diff --git a/src/value-serializer.cc b/src/value-serializer.cc |
| index 0c2a61b472046a00cd3a30b8d2bc4535c130db35..86abe12eef2b8a4ad56697a9a903e5655401eb11 100644 |
| --- a/src/value-serializer.cc |
| +++ b/src/value-serializer.cc |
| @@ -72,6 +72,13 @@ enum class SerializationTag : uint8_t { |
| kEndDenseJSArray = '$', |
| // Date. millisSinceEpoch:double |
| kDate = 'D', |
| + // Boolean object. No data. |
| + kTrueObject = 'y', |
| + kFalseObject = 'x', |
| + // Number object. value:double |
| + kNumberObject = 'n', |
| + // String object, UTF-8 encoding. byteLength:uint32_t, then raw data. |
| + kStringObject = 's', |
| }; |
| ValueSerializer::ValueSerializer(Isolate* isolate) |
| @@ -141,6 +148,7 @@ void ValueSerializer::WriteTwoByteString(Vector<const uc16> chars) { |
| } |
| uint8_t* ValueSerializer::ReserveRawBytes(size_t bytes) { |
| + if (!bytes) return nullptr; |
|
jbroman
2016/08/19 19:11:16
This sometimes triggered the debug std::vector che
|
| auto old_size = buffer_.size(); |
| buffer_.resize(buffer_.size() + bytes); |
| return &buffer_[old_size]; |
| @@ -273,6 +281,8 @@ Maybe<bool> ValueSerializer::WriteJSReceiver(Handle<JSReceiver> receiver) { |
| case JS_DATE_TYPE: |
| WriteJSDate(JSDate::cast(*receiver)); |
| return Just(true); |
| + case JS_VALUE_TYPE: |
| + return WriteJSValue(Handle<JSValue>::cast(receiver)); |
| default: |
| UNIMPLEMENTED(); |
| break; |
| @@ -363,6 +373,37 @@ void ValueSerializer::WriteJSDate(JSDate* date) { |
| WriteDouble(date->value()->Number()); |
| } |
| +Maybe<bool> ValueSerializer::WriteJSValue(Handle<JSValue> value) { |
| + Object* inner_value = value->value(); |
| + if (value->HasSpecificClassOf(isolate_->heap()->Boolean_string())) { |
| + if (inner_value->IsTrue(isolate_)) { |
| + WriteTag(SerializationTag::kTrueObject); |
| + } else { |
| + DCHECK(inner_value->IsFalse(isolate_)); |
| + WriteTag(SerializationTag::kFalseObject); |
| + } |
| + } else if (value->HasSpecificClassOf(isolate_->heap()->Number_string())) { |
| + DCHECK(inner_value->IsNumber()); |
| + WriteTag(SerializationTag::kNumberObject); |
| + WriteDouble(inner_value->Number()); |
| + } else if (value->HasSpecificClassOf(isolate_->heap()->String_string())) { |
| + DCHECK(inner_value->IsString()); |
| + // TODO(jbroman): Replace UTF-8 encoding with the same options available for |
| + // ordinary strings. |
| + WriteTag(SerializationTag::kStringObject); |
| + v8::Local<v8::String> api_string = |
| + Utils::ToLocal(handle(String::cast(inner_value), isolate_)); |
| + uint32_t utf8_length = api_string->Utf8Length(); |
| + WriteVarint(utf8_length); |
| + api_string->WriteUtf8(reinterpret_cast<char*>(ReserveRawBytes(utf8_length)), |
| + utf8_length, nullptr, |
| + v8::String::NO_NULL_TERMINATION); |
| + } else { |
| + return Nothing<bool>(); |
| + } |
| + return Just(true); |
| +} |
| + |
| Maybe<uint32_t> ValueSerializer::WriteJSObjectProperties( |
| Handle<JSObject> object, Handle<FixedArray> keys) { |
| uint32_t properties_written = 0; |
| @@ -545,6 +586,11 @@ MaybeHandle<Object> ValueDeserializer::ReadObject() { |
| return ReadDenseJSArray(); |
| case SerializationTag::kDate: |
| return ReadJSDate(); |
| + case SerializationTag::kTrueObject: |
| + case SerializationTag::kFalseObject: |
| + case SerializationTag::kNumberObject: |
| + case SerializationTag::kStringObject: |
| + return ReadJSValue(tag); |
| default: |
| return MaybeHandle<Object>(); |
| } |
| @@ -686,6 +732,43 @@ MaybeHandle<JSDate> ValueDeserializer::ReadJSDate() { |
| return date; |
| } |
| +MaybeHandle<JSValue> ValueDeserializer::ReadJSValue(SerializationTag tag) { |
| + uint32_t id = next_id_++; |
| + Handle<JSValue> value; |
| + switch (tag) { |
| + case SerializationTag::kTrueObject: |
| + value = Handle<JSValue>::cast( |
| + isolate_->factory()->NewJSObject(isolate_->boolean_function())); |
| + value->set_value(isolate_->heap()->true_value()); |
| + break; |
| + case SerializationTag::kFalseObject: |
| + value = Handle<JSValue>::cast( |
| + isolate_->factory()->NewJSObject(isolate_->boolean_function())); |
| + value->set_value(isolate_->heap()->false_value()); |
| + break; |
| + case SerializationTag::kNumberObject: { |
| + double number; |
| + if (!ReadDouble().To(&number)) return MaybeHandle<JSValue>(); |
| + value = Handle<JSValue>::cast( |
| + isolate_->factory()->NewJSObject(isolate_->number_function())); |
| + value->set_value(*isolate_->factory()->NewNumber(number)); |
| + break; |
| + } |
| + case SerializationTag::kStringObject: { |
| + Handle<String> string; |
| + if (!ReadUtf8String().ToHandle(&string)) return MaybeHandle<JSValue>(); |
| + value = Handle<JSValue>::cast( |
| + isolate_->factory()->NewJSObject(isolate_->string_function())); |
| + value->set_value(*string); |
| + break; |
| + } |
| + default: |
| + return MaybeHandle<JSValue>(); |
| + } |
| + AddObjectWithID(id, value); |
| + return value; |
| +} |
| + |
| Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties( |
| Handle<JSObject> object, SerializationTag end_tag) { |
| for (uint32_t num_properties = 0;; num_properties++) { |