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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 kEndDenseJSArray = '$', | 72 kEndDenseJSArray = '$', |
73 // Date. millisSinceEpoch:double | 73 // Date. millisSinceEpoch:double |
74 kDate = 'D', | 74 kDate = 'D', |
75 // Boolean object. No data. | 75 // Boolean object. No data. |
76 kTrueObject = 'y', | 76 kTrueObject = 'y', |
77 kFalseObject = 'x', | 77 kFalseObject = 'x', |
78 // Number object. value:double | 78 // Number object. value:double |
79 kNumberObject = 'n', | 79 kNumberObject = 'n', |
80 // String object, UTF-8 encoding. byteLength:uint32_t, then raw data. | 80 // String object, UTF-8 encoding. byteLength:uint32_t, then raw data. |
81 kStringObject = 's', | 81 kStringObject = 's', |
| 82 // Regular expression, UTF-8 encoding. byteLength:uint32_t, raw data, |
| 83 // flags:uint32_t. |
| 84 kRegExp = 'R', |
82 }; | 85 }; |
83 | 86 |
84 ValueSerializer::ValueSerializer(Isolate* isolate) | 87 ValueSerializer::ValueSerializer(Isolate* isolate) |
85 : isolate_(isolate), | 88 : isolate_(isolate), |
86 zone_(isolate->allocator()), | 89 zone_(isolate->allocator()), |
87 id_map_(isolate->heap(), &zone_) {} | 90 id_map_(isolate->heap(), &zone_) {} |
88 | 91 |
89 ValueSerializer::~ValueSerializer() {} | 92 ValueSerializer::~ValueSerializer() {} |
90 | 93 |
91 void ValueSerializer::WriteHeader() { | 94 void ValueSerializer::WriteHeader() { |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 case JS_ARRAY_TYPE: | 279 case JS_ARRAY_TYPE: |
277 return WriteJSArray(Handle<JSArray>::cast(receiver)); | 280 return WriteJSArray(Handle<JSArray>::cast(receiver)); |
278 case JS_OBJECT_TYPE: | 281 case JS_OBJECT_TYPE: |
279 case JS_API_OBJECT_TYPE: | 282 case JS_API_OBJECT_TYPE: |
280 return WriteJSObject(Handle<JSObject>::cast(receiver)); | 283 return WriteJSObject(Handle<JSObject>::cast(receiver)); |
281 case JS_DATE_TYPE: | 284 case JS_DATE_TYPE: |
282 WriteJSDate(JSDate::cast(*receiver)); | 285 WriteJSDate(JSDate::cast(*receiver)); |
283 return Just(true); | 286 return Just(true); |
284 case JS_VALUE_TYPE: | 287 case JS_VALUE_TYPE: |
285 return WriteJSValue(Handle<JSValue>::cast(receiver)); | 288 return WriteJSValue(Handle<JSValue>::cast(receiver)); |
| 289 case JS_REGEXP_TYPE: |
| 290 WriteJSRegExp(JSRegExp::cast(*receiver)); |
| 291 return Just(true); |
286 default: | 292 default: |
287 UNIMPLEMENTED(); | 293 UNIMPLEMENTED(); |
288 break; | 294 break; |
289 } | 295 } |
290 return Nothing<bool>(); | 296 return Nothing<bool>(); |
291 } | 297 } |
292 | 298 |
293 Maybe<bool> ValueSerializer::WriteJSObject(Handle<JSObject> object) { | 299 Maybe<bool> ValueSerializer::WriteJSObject(Handle<JSObject> object) { |
294 WriteTag(SerializationTag::kBeginJSObject); | 300 WriteTag(SerializationTag::kBeginJSObject); |
295 Handle<FixedArray> keys; | 301 Handle<FixedArray> keys; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 api_string->WriteUtf8(reinterpret_cast<char*>(ReserveRawBytes(utf8_length)), | 399 api_string->WriteUtf8(reinterpret_cast<char*>(ReserveRawBytes(utf8_length)), |
394 utf8_length, nullptr, | 400 utf8_length, nullptr, |
395 v8::String::NO_NULL_TERMINATION); | 401 v8::String::NO_NULL_TERMINATION); |
396 } else { | 402 } else { |
397 DCHECK(inner_value->IsSymbol()); | 403 DCHECK(inner_value->IsSymbol()); |
398 return Nothing<bool>(); | 404 return Nothing<bool>(); |
399 } | 405 } |
400 return Just(true); | 406 return Just(true); |
401 } | 407 } |
402 | 408 |
| 409 void ValueSerializer::WriteJSRegExp(JSRegExp* regexp) { |
| 410 WriteTag(SerializationTag::kRegExp); |
| 411 v8::Local<v8::String> api_string = |
| 412 Utils::ToLocal(handle(regexp->Pattern(), isolate_)); |
| 413 uint32_t utf8_length = api_string->Utf8Length(); |
| 414 WriteVarint(utf8_length); |
| 415 api_string->WriteUtf8(reinterpret_cast<char*>(ReserveRawBytes(utf8_length)), |
| 416 utf8_length, nullptr, v8::String::NO_NULL_TERMINATION); |
| 417 WriteVarint(static_cast<uint32_t>(regexp->GetFlags())); |
| 418 } |
| 419 |
403 Maybe<uint32_t> ValueSerializer::WriteJSObjectProperties( | 420 Maybe<uint32_t> ValueSerializer::WriteJSObjectProperties( |
404 Handle<JSObject> object, Handle<FixedArray> keys) { | 421 Handle<JSObject> object, Handle<FixedArray> keys) { |
405 uint32_t properties_written = 0; | 422 uint32_t properties_written = 0; |
406 int length = keys->length(); | 423 int length = keys->length(); |
407 for (int i = 0; i < length; i++) { | 424 for (int i = 0; i < length; i++) { |
408 Handle<Object> key(keys->get(i), isolate_); | 425 Handle<Object> key(keys->get(i), isolate_); |
409 | 426 |
410 bool success; | 427 bool success; |
411 LookupIterator it = LookupIterator::PropertyOrElement( | 428 LookupIterator it = LookupIterator::PropertyOrElement( |
412 isolate_, object, key, &success, LookupIterator::OWN); | 429 isolate_, object, key, &success, LookupIterator::OWN); |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 return ReadSparseJSArray(); | 597 return ReadSparseJSArray(); |
581 case SerializationTag::kBeginDenseJSArray: | 598 case SerializationTag::kBeginDenseJSArray: |
582 return ReadDenseJSArray(); | 599 return ReadDenseJSArray(); |
583 case SerializationTag::kDate: | 600 case SerializationTag::kDate: |
584 return ReadJSDate(); | 601 return ReadJSDate(); |
585 case SerializationTag::kTrueObject: | 602 case SerializationTag::kTrueObject: |
586 case SerializationTag::kFalseObject: | 603 case SerializationTag::kFalseObject: |
587 case SerializationTag::kNumberObject: | 604 case SerializationTag::kNumberObject: |
588 case SerializationTag::kStringObject: | 605 case SerializationTag::kStringObject: |
589 return ReadJSValue(tag); | 606 return ReadJSValue(tag); |
| 607 case SerializationTag::kRegExp: |
| 608 return ReadJSRegExp(); |
590 default: | 609 default: |
591 return MaybeHandle<Object>(); | 610 return MaybeHandle<Object>(); |
592 } | 611 } |
593 } | 612 } |
594 | 613 |
595 MaybeHandle<String> ValueDeserializer::ReadUtf8String() { | 614 MaybeHandle<String> ValueDeserializer::ReadUtf8String() { |
596 uint32_t utf8_length; | 615 uint32_t utf8_length; |
597 Vector<const uint8_t> utf8_bytes; | 616 Vector<const uint8_t> utf8_bytes; |
598 if (!ReadVarint<uint32_t>().To(&utf8_length) || | 617 if (!ReadVarint<uint32_t>().To(&utf8_length) || |
599 utf8_length > | 618 utf8_length > |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 break; | 779 break; |
761 } | 780 } |
762 default: | 781 default: |
763 UNREACHABLE(); | 782 UNREACHABLE(); |
764 return MaybeHandle<JSValue>(); | 783 return MaybeHandle<JSValue>(); |
765 } | 784 } |
766 AddObjectWithID(id, value); | 785 AddObjectWithID(id, value); |
767 return value; | 786 return value; |
768 } | 787 } |
769 | 788 |
| 789 MaybeHandle<JSRegExp> ValueDeserializer::ReadJSRegExp() { |
| 790 uint32_t id = next_id_++; |
| 791 Handle<String> pattern; |
| 792 uint32_t raw_flags; |
| 793 Handle<JSRegExp> regexp; |
| 794 if (!ReadUtf8String().ToHandle(&pattern) || |
| 795 !ReadVarint<uint32_t>().To(&raw_flags) || |
| 796 !JSRegExp::New(pattern, static_cast<JSRegExp::Flags>(raw_flags)) |
| 797 .ToHandle(®exp)) { |
| 798 return MaybeHandle<JSRegExp>(); |
| 799 } |
| 800 AddObjectWithID(id, regexp); |
| 801 return regexp; |
| 802 } |
| 803 |
770 Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties( | 804 Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties( |
771 Handle<JSObject> object, SerializationTag end_tag) { | 805 Handle<JSObject> object, SerializationTag end_tag) { |
772 for (uint32_t num_properties = 0;; num_properties++) { | 806 for (uint32_t num_properties = 0;; num_properties++) { |
773 SerializationTag tag; | 807 SerializationTag tag; |
774 if (!PeekTag().To(&tag)) return Nothing<uint32_t>(); | 808 if (!PeekTag().To(&tag)) return Nothing<uint32_t>(); |
775 if (tag == end_tag) { | 809 if (tag == end_tag) { |
776 ConsumeTag(end_tag); | 810 ConsumeTag(end_tag); |
777 return Just(num_properties); | 811 return Just(num_properties); |
778 } | 812 } |
779 | 813 |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
924 } | 958 } |
925 #endif | 959 #endif |
926 position_ = end_; | 960 position_ = end_; |
927 | 961 |
928 if (stack.size() != 1) return MaybeHandle<Object>(); | 962 if (stack.size() != 1) return MaybeHandle<Object>(); |
929 return scope.CloseAndEscape(stack[0]); | 963 return scope.CloseAndEscape(stack[0]); |
930 } | 964 } |
931 | 965 |
932 } // namespace internal | 966 } // namespace internal |
933 } // namespace v8 | 967 } // namespace v8 |
OLD | NEW |