| 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 |