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 <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "include/v8.h" | 10 #include "include/v8.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 } | 79 } |
80 | 80 |
81 // Variant for the common case where a script is used to build the original | 81 // Variant for the common case where a script is used to build the original |
82 // value. | 82 // value. |
83 template <typename OutputFunctor> | 83 template <typename OutputFunctor> |
84 void RoundTripTest(const char* source, const OutputFunctor& output_functor) { | 84 void RoundTripTest(const char* source, const OutputFunctor& output_functor) { |
85 RoundTripTest([this, source]() { return EvaluateScriptForInput(source); }, | 85 RoundTripTest([this, source]() { return EvaluateScriptForInput(source); }, |
86 output_functor); | 86 output_functor); |
87 } | 87 } |
88 | 88 |
| 89 // Variant which uses JSON.parse/stringify to check the result. |
| 90 void RoundTripJSON(const char* source) { |
| 91 RoundTripTest( |
| 92 [this, source]() { |
| 93 return JSON::Parse(serialization_context_, StringFromUtf8(source)) |
| 94 .ToLocalChecked(); |
| 95 }, |
| 96 [this, source](Local<Value> value) { |
| 97 ASSERT_TRUE(value->IsObject()); |
| 98 EXPECT_EQ(source, Utf8Value(JSON::Stringify(deserialization_context_, |
| 99 value.As<Object>()) |
| 100 .ToLocalChecked())); |
| 101 }); |
| 102 } |
| 103 |
89 Maybe<std::vector<uint8_t>> DoEncode(Local<Value> value) { | 104 Maybe<std::vector<uint8_t>> DoEncode(Local<Value> value) { |
90 Local<Context> context = serialization_context(); | 105 Local<Context> context = serialization_context(); |
91 ValueSerializer serializer(isolate(), GetSerializerDelegate()); | 106 ValueSerializer serializer(isolate(), GetSerializerDelegate()); |
92 BeforeEncode(&serializer); | 107 BeforeEncode(&serializer); |
93 serializer.WriteHeader(); | 108 serializer.WriteHeader(); |
94 if (!serializer.WriteValue(context, value).FromMaybe(false)) { | 109 if (!serializer.WriteValue(context, value).FromMaybe(false)) { |
95 return Nothing<std::vector<uint8_t>>(); | 110 return Nothing<std::vector<uint8_t>>(); |
96 } | 111 } |
97 return Just(serializer.ReleaseBuffer()); | 112 return Just(serializer.ReleaseBuffer()); |
98 } | 113 } |
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 // If an exception is thrown by script, encoding must fail and the exception | 712 // If an exception is thrown by script, encoding must fail and the exception |
698 // must be thrown. | 713 // must be thrown. |
699 InvalidEncodeTest("({ get a() { throw new Error('sentinel'); } })", | 714 InvalidEncodeTest("({ get a() { throw new Error('sentinel'); } })", |
700 [](Local<Message> message) { | 715 [](Local<Message> message) { |
701 ASSERT_FALSE(message.IsEmpty()); | 716 ASSERT_FALSE(message.IsEmpty()); |
702 EXPECT_NE(std::string::npos, | 717 EXPECT_NE(std::string::npos, |
703 Utf8Value(message->Get()).find("sentinel")); | 718 Utf8Value(message->Get()).find("sentinel")); |
704 }); | 719 }); |
705 } | 720 } |
706 | 721 |
| 722 TEST_F(ValueSerializerTest, RoundTripDictionaryObjectForTransitions) { |
| 723 // A case which should run on the fast path, and should reach all of the |
| 724 // different cases: |
| 725 // 1. no known transition (first time creating this kind of object) |
| 726 // 2. expected transitions match to end |
| 727 // 3. transition partially matches, but falls back due to new property 'w' |
| 728 // 4. transition to 'z' is now a full transition (needs to be looked up) |
| 729 // 5. same for 'w' |
| 730 // 6. new property after complex transition succeeded |
| 731 // 7. new property after complex transition failed (due to new property) |
| 732 RoundTripJSON( |
| 733 "[{\"x\":1,\"y\":2,\"z\":3}" |
| 734 ",{\"x\":4,\"y\":5,\"z\":6}" |
| 735 ",{\"x\":5,\"y\":6,\"w\":7}" |
| 736 ",{\"x\":6,\"y\":7,\"z\":8}" |
| 737 ",{\"x\":0,\"y\":0,\"w\":0}" |
| 738 ",{\"x\":3,\"y\":1,\"w\":4,\"z\":1}" |
| 739 ",{\"x\":5,\"y\":9,\"k\":2,\"z\":6}]"); |
| 740 // A simpler case that uses two-byte strings. |
| 741 RoundTripJSON( |
| 742 "[{\"\xF0\x9F\x91\x8A\":1,\"\xF0\x9F\x91\x8B\":2}" |
| 743 ",{\"\xF0\x9F\x91\x8A\":3,\"\xF0\x9F\x91\x8C\":4}" |
| 744 ",{\"\xF0\x9F\x91\x8A\":5,\"\xF0\x9F\x91\x9B\":6}]"); |
| 745 } |
| 746 |
707 TEST_F(ValueSerializerTest, DecodeDictionaryObjectVersion0) { | 747 TEST_F(ValueSerializerTest, DecodeDictionaryObjectVersion0) { |
708 // Empty object. | 748 // Empty object. |
709 DecodeTestForVersion0( | 749 DecodeTestForVersion0( |
710 {0x7b, 0x00}, | 750 {0x7b, 0x00}, |
711 [this](Local<Value> value) { | 751 [this](Local<Value> value) { |
712 ASSERT_TRUE(value->IsObject()); | 752 ASSERT_TRUE(value->IsObject()); |
713 EXPECT_TRUE(EvaluateScriptForResultBool( | 753 EXPECT_TRUE(EvaluateScriptForResultBool( |
714 "Object.getPrototypeOf(result) === Object.prototype")); | 754 "Object.getPrototypeOf(result) === Object.prototype")); |
715 EXPECT_TRUE(EvaluateScriptForResultBool( | 755 EXPECT_TRUE(EvaluateScriptForResultBool( |
716 "Object.getOwnPropertyNames(result).length === 0")); | 756 "Object.getOwnPropertyNames(result).length === 0")); |
(...skipping 1558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2275 "({ a: new ExampleHostObject(), get b() { return this.a; }})", | 2315 "({ a: new ExampleHostObject(), get b() { return this.a; }})", |
2276 [this](Local<Value> value) { | 2316 [this](Local<Value> value) { |
2277 EXPECT_TRUE(EvaluateScriptForResultBool( | 2317 EXPECT_TRUE(EvaluateScriptForResultBool( |
2278 "result.a instanceof ExampleHostObject")); | 2318 "result.a instanceof ExampleHostObject")); |
2279 EXPECT_TRUE(EvaluateScriptForResultBool("result.a === result.b")); | 2319 EXPECT_TRUE(EvaluateScriptForResultBool("result.a === result.b")); |
2280 }); | 2320 }); |
2281 } | 2321 } |
2282 | 2322 |
2283 } // namespace | 2323 } // namespace |
2284 } // namespace v8 | 2324 } // namespace v8 |
OLD | NEW |