Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/value-serializer.cc

Issue 2265603002: Blink-compatible serialization of Boolean, Number and String objects. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@vs-date
Patch Set: remove HasSpecificClassOf Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/value-serializer.h ('k') | test/unittests/value-serializer-unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/value-serializer.h" 5 #include "src/value-serializer.h"
6 6
7 #include <type_traits> 7 #include <type_traits>
8 8
9 #include "src/base/logging.h" 9 #include "src/base/logging.h"
10 #include "src/factory.h" 10 #include "src/factory.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 kBeginSparseJSArray = 'a', 65 kBeginSparseJSArray = 'a',
66 // End of a sparse JS array. numProperties:uint32_t length:uint32_t 66 // End of a sparse JS array. numProperties:uint32_t length:uint32_t
67 kEndSparseJSArray = '@', 67 kEndSparseJSArray = '@',
68 // Beginning of a dense JS array. length:uint32_t 68 // Beginning of a dense JS array. length:uint32_t
69 // |length| elements, followed by properties as key/value pairs 69 // |length| elements, followed by properties as key/value pairs
70 kBeginDenseJSArray = 'A', 70 kBeginDenseJSArray = 'A',
71 // End of a dense JS array. numProperties:uint32_t length:uint32_t 71 // End of a dense JS array. numProperties:uint32_t length:uint32_t
72 kEndDenseJSArray = '$', 72 kEndDenseJSArray = '$',
73 // Date. millisSinceEpoch:double 73 // Date. millisSinceEpoch:double
74 kDate = 'D', 74 kDate = 'D',
75 // Boolean object. No data.
76 kTrueObject = 'y',
77 kFalseObject = 'x',
78 // Number object. value:double
79 kNumberObject = 'n',
80 // String object, UTF-8 encoding. byteLength:uint32_t, then raw data.
81 kStringObject = 's',
75 }; 82 };
76 83
77 ValueSerializer::ValueSerializer(Isolate* isolate) 84 ValueSerializer::ValueSerializer(Isolate* isolate)
78 : isolate_(isolate), 85 : isolate_(isolate),
79 zone_(isolate->allocator()), 86 zone_(isolate->allocator()),
80 id_map_(isolate->heap(), &zone_) {} 87 id_map_(isolate->heap(), &zone_) {}
81 88
82 ValueSerializer::~ValueSerializer() {} 89 ValueSerializer::~ValueSerializer() {}
83 90
84 void ValueSerializer::WriteHeader() { 91 void ValueSerializer::WriteHeader() {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 } 141 }
135 142
136 void ValueSerializer::WriteTwoByteString(Vector<const uc16> chars) { 143 void ValueSerializer::WriteTwoByteString(Vector<const uc16> chars) {
137 // Warning: this uses host endianness. 144 // Warning: this uses host endianness.
138 WriteVarint<uint32_t>(chars.length() * sizeof(uc16)); 145 WriteVarint<uint32_t>(chars.length() * sizeof(uc16));
139 buffer_.insert(buffer_.end(), reinterpret_cast<const uint8_t*>(chars.begin()), 146 buffer_.insert(buffer_.end(), reinterpret_cast<const uint8_t*>(chars.begin()),
140 reinterpret_cast<const uint8_t*>(chars.end())); 147 reinterpret_cast<const uint8_t*>(chars.end()));
141 } 148 }
142 149
143 uint8_t* ValueSerializer::ReserveRawBytes(size_t bytes) { 150 uint8_t* ValueSerializer::ReserveRawBytes(size_t bytes) {
151 if (!bytes) return nullptr;
144 auto old_size = buffer_.size(); 152 auto old_size = buffer_.size();
145 buffer_.resize(buffer_.size() + bytes); 153 buffer_.resize(buffer_.size() + bytes);
146 return &buffer_[old_size]; 154 return &buffer_[old_size];
147 } 155 }
148 156
149 Maybe<bool> ValueSerializer::WriteObject(Handle<Object> object) { 157 Maybe<bool> ValueSerializer::WriteObject(Handle<Object> object) {
150 if (object->IsSmi()) { 158 if (object->IsSmi()) {
151 WriteSmi(Smi::cast(*object)); 159 WriteSmi(Smi::cast(*object));
152 return Just(true); 160 return Just(true);
153 } 161 }
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 HandleScope scope(isolate_); 274 HandleScope scope(isolate_);
267 switch (instance_type) { 275 switch (instance_type) {
268 case JS_ARRAY_TYPE: 276 case JS_ARRAY_TYPE:
269 return WriteJSArray(Handle<JSArray>::cast(receiver)); 277 return WriteJSArray(Handle<JSArray>::cast(receiver));
270 case JS_OBJECT_TYPE: 278 case JS_OBJECT_TYPE:
271 case JS_API_OBJECT_TYPE: 279 case JS_API_OBJECT_TYPE:
272 return WriteJSObject(Handle<JSObject>::cast(receiver)); 280 return WriteJSObject(Handle<JSObject>::cast(receiver));
273 case JS_DATE_TYPE: 281 case JS_DATE_TYPE:
274 WriteJSDate(JSDate::cast(*receiver)); 282 WriteJSDate(JSDate::cast(*receiver));
275 return Just(true); 283 return Just(true);
284 case JS_VALUE_TYPE:
285 return WriteJSValue(Handle<JSValue>::cast(receiver));
276 default: 286 default:
277 UNIMPLEMENTED(); 287 UNIMPLEMENTED();
278 break; 288 break;
279 } 289 }
280 return Nothing<bool>(); 290 return Nothing<bool>();
281 } 291 }
282 292
283 Maybe<bool> ValueSerializer::WriteJSObject(Handle<JSObject> object) { 293 Maybe<bool> ValueSerializer::WriteJSObject(Handle<JSObject> object) {
284 WriteTag(SerializationTag::kBeginJSObject); 294 WriteTag(SerializationTag::kBeginJSObject);
285 Handle<FixedArray> keys; 295 Handle<FixedArray> keys;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 WriteVarint<uint32_t>(length); 366 WriteVarint<uint32_t>(length);
357 } 367 }
358 return Just(true); 368 return Just(true);
359 } 369 }
360 370
361 void ValueSerializer::WriteJSDate(JSDate* date) { 371 void ValueSerializer::WriteJSDate(JSDate* date) {
362 WriteTag(SerializationTag::kDate); 372 WriteTag(SerializationTag::kDate);
363 WriteDouble(date->value()->Number()); 373 WriteDouble(date->value()->Number());
364 } 374 }
365 375
376 Maybe<bool> ValueSerializer::WriteJSValue(Handle<JSValue> value) {
377 Object* inner_value = value->value();
378 if (inner_value->IsTrue(isolate_)) {
379 WriteTag(SerializationTag::kTrueObject);
380 } else if (inner_value->IsFalse(isolate_)) {
381 WriteTag(SerializationTag::kFalseObject);
382 } else if (inner_value->IsNumber()) {
383 WriteTag(SerializationTag::kNumberObject);
384 WriteDouble(inner_value->Number());
385 } else if (inner_value->IsString()) {
386 // TODO(jbroman): Replace UTF-8 encoding with the same options available for
387 // ordinary strings.
388 WriteTag(SerializationTag::kStringObject);
389 v8::Local<v8::String> api_string =
390 Utils::ToLocal(handle(String::cast(inner_value), isolate_));
391 uint32_t utf8_length = api_string->Utf8Length();
392 WriteVarint(utf8_length);
393 api_string->WriteUtf8(reinterpret_cast<char*>(ReserveRawBytes(utf8_length)),
394 utf8_length, nullptr,
395 v8::String::NO_NULL_TERMINATION);
396 } else {
397 DCHECK(inner_value->IsSymbol());
398 return Nothing<bool>();
399 }
400 return Just(true);
401 }
402
366 Maybe<uint32_t> ValueSerializer::WriteJSObjectProperties( 403 Maybe<uint32_t> ValueSerializer::WriteJSObjectProperties(
367 Handle<JSObject> object, Handle<FixedArray> keys) { 404 Handle<JSObject> object, Handle<FixedArray> keys) {
368 uint32_t properties_written = 0; 405 uint32_t properties_written = 0;
369 int length = keys->length(); 406 int length = keys->length();
370 for (int i = 0; i < length; i++) { 407 for (int i = 0; i < length; i++) {
371 Handle<Object> key(keys->get(i), isolate_); 408 Handle<Object> key(keys->get(i), isolate_);
372 409
373 bool success; 410 bool success;
374 LookupIterator it = LookupIterator::PropertyOrElement( 411 LookupIterator it = LookupIterator::PropertyOrElement(
375 isolate_, object, key, &success, LookupIterator::OWN); 412 isolate_, object, key, &success, LookupIterator::OWN);
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 return GetObjectWithID(id); 575 return GetObjectWithID(id);
539 } 576 }
540 case SerializationTag::kBeginJSObject: 577 case SerializationTag::kBeginJSObject:
541 return ReadJSObject(); 578 return ReadJSObject();
542 case SerializationTag::kBeginSparseJSArray: 579 case SerializationTag::kBeginSparseJSArray:
543 return ReadSparseJSArray(); 580 return ReadSparseJSArray();
544 case SerializationTag::kBeginDenseJSArray: 581 case SerializationTag::kBeginDenseJSArray:
545 return ReadDenseJSArray(); 582 return ReadDenseJSArray();
546 case SerializationTag::kDate: 583 case SerializationTag::kDate:
547 return ReadJSDate(); 584 return ReadJSDate();
585 case SerializationTag::kTrueObject:
586 case SerializationTag::kFalseObject:
587 case SerializationTag::kNumberObject:
588 case SerializationTag::kStringObject:
589 return ReadJSValue(tag);
548 default: 590 default:
549 return MaybeHandle<Object>(); 591 return MaybeHandle<Object>();
550 } 592 }
551 } 593 }
552 594
553 MaybeHandle<String> ValueDeserializer::ReadUtf8String() { 595 MaybeHandle<String> ValueDeserializer::ReadUtf8String() {
554 uint32_t utf8_length; 596 uint32_t utf8_length;
555 Vector<const uint8_t> utf8_bytes; 597 Vector<const uint8_t> utf8_bytes;
556 if (!ReadVarint<uint32_t>().To(&utf8_length) || 598 if (!ReadVarint<uint32_t>().To(&utf8_length) ||
557 utf8_length > 599 utf8_length >
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 uint32_t id = next_id_++; 721 uint32_t id = next_id_++;
680 Handle<JSDate> date; 722 Handle<JSDate> date;
681 if (!JSDate::New(isolate_->date_function(), isolate_->date_function(), value) 723 if (!JSDate::New(isolate_->date_function(), isolate_->date_function(), value)
682 .ToHandle(&date)) { 724 .ToHandle(&date)) {
683 return MaybeHandle<JSDate>(); 725 return MaybeHandle<JSDate>();
684 } 726 }
685 AddObjectWithID(id, date); 727 AddObjectWithID(id, date);
686 return date; 728 return date;
687 } 729 }
688 730
731 MaybeHandle<JSValue> ValueDeserializer::ReadJSValue(SerializationTag tag) {
732 uint32_t id = next_id_++;
733 Handle<JSValue> value;
734 switch (tag) {
735 case SerializationTag::kTrueObject:
736 value = Handle<JSValue>::cast(
737 isolate_->factory()->NewJSObject(isolate_->boolean_function()));
738 value->set_value(isolate_->heap()->true_value());
739 break;
740 case SerializationTag::kFalseObject:
741 value = Handle<JSValue>::cast(
742 isolate_->factory()->NewJSObject(isolate_->boolean_function()));
743 value->set_value(isolate_->heap()->false_value());
744 break;
745 case SerializationTag::kNumberObject: {
746 double number;
747 if (!ReadDouble().To(&number)) return MaybeHandle<JSValue>();
748 value = Handle<JSValue>::cast(
749 isolate_->factory()->NewJSObject(isolate_->number_function()));
750 Handle<Object> number_object = isolate_->factory()->NewNumber(number);
751 value->set_value(*number_object);
752 break;
753 }
754 case SerializationTag::kStringObject: {
755 Handle<String> string;
756 if (!ReadUtf8String().ToHandle(&string)) return MaybeHandle<JSValue>();
757 value = Handle<JSValue>::cast(
758 isolate_->factory()->NewJSObject(isolate_->string_function()));
759 value->set_value(*string);
760 break;
761 }
762 default:
763 UNREACHABLE();
764 return MaybeHandle<JSValue>();
765 }
766 AddObjectWithID(id, value);
767 return value;
768 }
769
689 Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties( 770 Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties(
690 Handle<JSObject> object, SerializationTag end_tag) { 771 Handle<JSObject> object, SerializationTag end_tag) {
691 for (uint32_t num_properties = 0;; num_properties++) { 772 for (uint32_t num_properties = 0;; num_properties++) {
692 SerializationTag tag; 773 SerializationTag tag;
693 if (!PeekTag().To(&tag)) return Nothing<uint32_t>(); 774 if (!PeekTag().To(&tag)) return Nothing<uint32_t>();
694 if (tag == end_tag) { 775 if (tag == end_tag) {
695 ConsumeTag(end_tag); 776 ConsumeTag(end_tag);
696 return Just(num_properties); 777 return Just(num_properties);
697 } 778 }
698 779
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 } 924 }
844 #endif 925 #endif
845 position_ = end_; 926 position_ = end_;
846 927
847 if (stack.size() != 1) return MaybeHandle<Object>(); 928 if (stack.size() != 1) return MaybeHandle<Object>();
848 return scope.CloseAndEscape(stack[0]); 929 return scope.CloseAndEscape(stack[0]);
849 } 930 }
850 931
851 } // namespace internal 932 } // namespace internal
852 } // namespace v8 933 } // namespace v8
OLDNEW
« no previous file with comments | « src/value-serializer.h ('k') | test/unittests/value-serializer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698