| Index: src/value-serializer.cc
|
| diff --git a/src/value-serializer.cc b/src/value-serializer.cc
|
| index 0c2a61b472046a00cd3a30b8d2bc4535c130db35..32f41e925efb7fc522cae66f63cd57707d2853ec 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;
|
| 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,33 @@ void ValueSerializer::WriteJSDate(JSDate* date) {
|
| WriteDouble(date->value()->Number());
|
| }
|
|
|
| +Maybe<bool> ValueSerializer::WriteJSValue(Handle<JSValue> value) {
|
| + Object* inner_value = value->value();
|
| + if (inner_value->IsTrue(isolate_)) {
|
| + WriteTag(SerializationTag::kTrueObject);
|
| + } else if (inner_value->IsFalse(isolate_)) {
|
| + WriteTag(SerializationTag::kFalseObject);
|
| + } else if (inner_value->IsNumber()) {
|
| + WriteTag(SerializationTag::kNumberObject);
|
| + WriteDouble(inner_value->Number());
|
| + } else if (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 {
|
| + DCHECK(inner_value->IsSymbol());
|
| + return Nothing<bool>();
|
| + }
|
| + return Just(true);
|
| +}
|
| +
|
| Maybe<uint32_t> ValueSerializer::WriteJSObjectProperties(
|
| Handle<JSObject> object, Handle<FixedArray> keys) {
|
| uint32_t properties_written = 0;
|
| @@ -545,6 +582,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 +728,45 @@ 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()));
|
| + Handle<Object> number_object = isolate_->factory()->NewNumber(number);
|
| + value->set_value(*number_object);
|
| + 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:
|
| + UNREACHABLE();
|
| + 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++) {
|
|
|