OLD | NEW |
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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 // Beginning of a sparse JS array. length:uint32_t | 63 // Beginning of a sparse JS array. length:uint32_t |
64 // Elements and properties are written as key/value pairs, like objects. | 64 // Elements and properties are written as key/value pairs, like objects. |
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 |
| 74 kDate = 'D', |
73 }; | 75 }; |
74 | 76 |
75 ValueSerializer::ValueSerializer(Isolate* isolate) | 77 ValueSerializer::ValueSerializer(Isolate* isolate) |
76 : isolate_(isolate), | 78 : isolate_(isolate), |
77 zone_(isolate->allocator()), | 79 zone_(isolate->allocator()), |
78 id_map_(isolate->heap(), &zone_) {} | 80 id_map_(isolate->heap(), &zone_) {} |
79 | 81 |
80 ValueSerializer::~ValueSerializer() {} | 82 ValueSerializer::~ValueSerializer() {} |
81 | 83 |
82 void ValueSerializer::WriteHeader() { | 84 void ValueSerializer::WriteHeader() { |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 // If we are at the end of the stack, abort. This function may recurse. | 263 // If we are at the end of the stack, abort. This function may recurse. |
262 if (StackLimitCheck(isolate_).HasOverflowed()) return Nothing<bool>(); | 264 if (StackLimitCheck(isolate_).HasOverflowed()) return Nothing<bool>(); |
263 | 265 |
264 HandleScope scope(isolate_); | 266 HandleScope scope(isolate_); |
265 switch (instance_type) { | 267 switch (instance_type) { |
266 case JS_ARRAY_TYPE: | 268 case JS_ARRAY_TYPE: |
267 return WriteJSArray(Handle<JSArray>::cast(receiver)); | 269 return WriteJSArray(Handle<JSArray>::cast(receiver)); |
268 case JS_OBJECT_TYPE: | 270 case JS_OBJECT_TYPE: |
269 case JS_API_OBJECT_TYPE: | 271 case JS_API_OBJECT_TYPE: |
270 return WriteJSObject(Handle<JSObject>::cast(receiver)); | 272 return WriteJSObject(Handle<JSObject>::cast(receiver)); |
| 273 case JS_DATE_TYPE: |
| 274 WriteJSDate(JSDate::cast(*receiver)); |
| 275 return Just(true); |
271 default: | 276 default: |
272 UNIMPLEMENTED(); | 277 UNIMPLEMENTED(); |
273 break; | 278 break; |
274 } | 279 } |
275 return Nothing<bool>(); | 280 return Nothing<bool>(); |
276 } | 281 } |
277 | 282 |
278 Maybe<bool> ValueSerializer::WriteJSObject(Handle<JSObject> object) { | 283 Maybe<bool> ValueSerializer::WriteJSObject(Handle<JSObject> object) { |
279 WriteTag(SerializationTag::kBeginJSObject); | 284 WriteTag(SerializationTag::kBeginJSObject); |
280 Handle<FixedArray> keys; | 285 Handle<FixedArray> keys; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 !WriteJSObjectProperties(array, keys).To(&properties_written)) { | 351 !WriteJSObjectProperties(array, keys).To(&properties_written)) { |
347 return Nothing<bool>(); | 352 return Nothing<bool>(); |
348 } | 353 } |
349 WriteTag(SerializationTag::kEndSparseJSArray); | 354 WriteTag(SerializationTag::kEndSparseJSArray); |
350 WriteVarint<uint32_t>(properties_written); | 355 WriteVarint<uint32_t>(properties_written); |
351 WriteVarint<uint32_t>(length); | 356 WriteVarint<uint32_t>(length); |
352 } | 357 } |
353 return Just(true); | 358 return Just(true); |
354 } | 359 } |
355 | 360 |
| 361 void ValueSerializer::WriteJSDate(JSDate* date) { |
| 362 WriteTag(SerializationTag::kDate); |
| 363 WriteDouble(date->value()->Number()); |
| 364 } |
| 365 |
356 Maybe<uint32_t> ValueSerializer::WriteJSObjectProperties( | 366 Maybe<uint32_t> ValueSerializer::WriteJSObjectProperties( |
357 Handle<JSObject> object, Handle<FixedArray> keys) { | 367 Handle<JSObject> object, Handle<FixedArray> keys) { |
358 uint32_t properties_written = 0; | 368 uint32_t properties_written = 0; |
359 int length = keys->length(); | 369 int length = keys->length(); |
360 for (int i = 0; i < length; i++) { | 370 for (int i = 0; i < length; i++) { |
361 Handle<Object> key(keys->get(i), isolate_); | 371 Handle<Object> key(keys->get(i), isolate_); |
362 | 372 |
363 bool success; | 373 bool success; |
364 LookupIterator it = LookupIterator::PropertyOrElement( | 374 LookupIterator it = LookupIterator::PropertyOrElement( |
365 isolate_, object, key, &success, LookupIterator::OWN); | 375 isolate_, object, key, &success, LookupIterator::OWN); |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 uint32_t id; | 536 uint32_t id; |
527 if (!ReadVarint<uint32_t>().To(&id)) return MaybeHandle<Object>(); | 537 if (!ReadVarint<uint32_t>().To(&id)) return MaybeHandle<Object>(); |
528 return GetObjectWithID(id); | 538 return GetObjectWithID(id); |
529 } | 539 } |
530 case SerializationTag::kBeginJSObject: | 540 case SerializationTag::kBeginJSObject: |
531 return ReadJSObject(); | 541 return ReadJSObject(); |
532 case SerializationTag::kBeginSparseJSArray: | 542 case SerializationTag::kBeginSparseJSArray: |
533 return ReadSparseJSArray(); | 543 return ReadSparseJSArray(); |
534 case SerializationTag::kBeginDenseJSArray: | 544 case SerializationTag::kBeginDenseJSArray: |
535 return ReadDenseJSArray(); | 545 return ReadDenseJSArray(); |
| 546 case SerializationTag::kDate: |
| 547 return ReadJSDate(); |
536 default: | 548 default: |
537 return MaybeHandle<Object>(); | 549 return MaybeHandle<Object>(); |
538 } | 550 } |
539 } | 551 } |
540 | 552 |
541 MaybeHandle<String> ValueDeserializer::ReadUtf8String() { | 553 MaybeHandle<String> ValueDeserializer::ReadUtf8String() { |
542 uint32_t utf8_length; | 554 uint32_t utf8_length; |
543 Vector<const uint8_t> utf8_bytes; | 555 Vector<const uint8_t> utf8_bytes; |
544 if (!ReadVarint<uint32_t>().To(&utf8_length) || | 556 if (!ReadVarint<uint32_t>().To(&utf8_length) || |
545 utf8_length > | 557 utf8_length > |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 !ReadVarint<uint32_t>().To(&expected_num_properties) || | 666 !ReadVarint<uint32_t>().To(&expected_num_properties) || |
655 !ReadVarint<uint32_t>().To(&expected_length) || | 667 !ReadVarint<uint32_t>().To(&expected_length) || |
656 num_properties != expected_num_properties || length != expected_length) { | 668 num_properties != expected_num_properties || length != expected_length) { |
657 return MaybeHandle<JSArray>(); | 669 return MaybeHandle<JSArray>(); |
658 } | 670 } |
659 | 671 |
660 DCHECK(HasObjectWithID(id)); | 672 DCHECK(HasObjectWithID(id)); |
661 return scope.CloseAndEscape(array); | 673 return scope.CloseAndEscape(array); |
662 } | 674 } |
663 | 675 |
| 676 MaybeHandle<JSDate> ValueDeserializer::ReadJSDate() { |
| 677 double value; |
| 678 if (!ReadDouble().To(&value)) return MaybeHandle<JSDate>(); |
| 679 uint32_t id = next_id_++; |
| 680 Handle<JSDate> date; |
| 681 if (!JSDate::New(isolate_->date_function(), isolate_->date_function(), value) |
| 682 .ToHandle(&date)) { |
| 683 return MaybeHandle<JSDate>(); |
| 684 } |
| 685 AddObjectWithID(id, date); |
| 686 return date; |
| 687 } |
| 688 |
664 Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties( | 689 Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties( |
665 Handle<JSObject> object, SerializationTag end_tag) { | 690 Handle<JSObject> object, SerializationTag end_tag) { |
666 for (uint32_t num_properties = 0;; num_properties++) { | 691 for (uint32_t num_properties = 0;; num_properties++) { |
667 SerializationTag tag; | 692 SerializationTag tag; |
668 if (!PeekTag().To(&tag)) return Nothing<uint32_t>(); | 693 if (!PeekTag().To(&tag)) return Nothing<uint32_t>(); |
669 if (tag == end_tag) { | 694 if (tag == end_tag) { |
670 ConsumeTag(end_tag); | 695 ConsumeTag(end_tag); |
671 return Just(num_properties); | 696 return Just(num_properties); |
672 } | 697 } |
673 | 698 |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 } | 843 } |
819 #endif | 844 #endif |
820 position_ = end_; | 845 position_ = end_; |
821 | 846 |
822 if (stack.size() != 1) return MaybeHandle<Object>(); | 847 if (stack.size() != 1) return MaybeHandle<Object>(); |
823 return scope.CloseAndEscape(stack[0]); | 848 return scope.CloseAndEscape(stack[0]); |
824 } | 849 } |
825 | 850 |
826 } // namespace internal | 851 } // namespace internal |
827 } // namespace v8 | 852 } // namespace v8 |
OLD | NEW |