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

Side by Side Diff: test/unittests/value-serializer-unittest.cc

Issue 2275033003: Blink-compatible serialization of ArrayBuffer transfer. (Closed)
Patch Set: Accepts Created 4 years, 3 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.cc ('k') | no next file » | 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 <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "include/v8.h" 10 #include "include/v8.h"
(...skipping 11 matching lines...) Expand all
22 : serialization_context_(Context::New(isolate())), 22 : serialization_context_(Context::New(isolate())),
23 deserialization_context_(Context::New(isolate())) {} 23 deserialization_context_(Context::New(isolate())) {}
24 24
25 const Local<Context>& serialization_context() { 25 const Local<Context>& serialization_context() {
26 return serialization_context_; 26 return serialization_context_;
27 } 27 }
28 const Local<Context>& deserialization_context() { 28 const Local<Context>& deserialization_context() {
29 return deserialization_context_; 29 return deserialization_context_;
30 } 30 }
31 31
32 // Overridden in more specific fixtures.
33 virtual void BeforeEncode(ValueSerializer*) {}
34 virtual void BeforeDecode(ValueDeserializer*) {}
35
32 template <typename InputFunctor, typename OutputFunctor> 36 template <typename InputFunctor, typename OutputFunctor>
33 void RoundTripTest(const InputFunctor& input_functor, 37 void RoundTripTest(const InputFunctor& input_functor,
34 const OutputFunctor& output_functor) { 38 const OutputFunctor& output_functor) {
35 EncodeTest(input_functor, 39 EncodeTest(input_functor,
36 [this, &output_functor](const std::vector<uint8_t>& data) { 40 [this, &output_functor](const std::vector<uint8_t>& data) {
37 DecodeTest(data, output_functor); 41 DecodeTest(data, output_functor);
38 }); 42 });
39 } 43 }
40 44
41 // Variant for the common case where a script is used to build the original 45 // Variant for the common case where a script is used to build the original
42 // value. 46 // value.
43 template <typename OutputFunctor> 47 template <typename OutputFunctor>
44 void RoundTripTest(const char* source, const OutputFunctor& output_functor) { 48 void RoundTripTest(const char* source, const OutputFunctor& output_functor) {
45 RoundTripTest([this, source]() { return EvaluateScriptForInput(source); }, 49 RoundTripTest([this, source]() { return EvaluateScriptForInput(source); },
46 output_functor); 50 output_functor);
47 } 51 }
48 52
49 Maybe<std::vector<uint8_t>> DoEncode(Local<Value> value) { 53 Maybe<std::vector<uint8_t>> DoEncode(Local<Value> value) {
50 Local<Context> context = serialization_context(); 54 Local<Context> context = serialization_context();
51 ValueSerializer serializer(isolate()); 55 ValueSerializer serializer(isolate());
56 BeforeEncode(&serializer);
52 serializer.WriteHeader(); 57 serializer.WriteHeader();
53 if (!serializer.WriteValue(context, value).FromMaybe(false)) { 58 if (!serializer.WriteValue(context, value).FromMaybe(false)) {
54 return Nothing<std::vector<uint8_t>>(); 59 return Nothing<std::vector<uint8_t>>();
55 } 60 }
56 return Just(serializer.ReleaseBuffer()); 61 return Just(serializer.ReleaseBuffer());
57 } 62 }
58 63
59 template <typename InputFunctor, typename EncodedDataFunctor> 64 template <typename InputFunctor, typename EncodedDataFunctor>
60 void EncodeTest(const InputFunctor& input_functor, 65 void EncodeTest(const InputFunctor& input_functor,
61 const EncodedDataFunctor& encoded_data_functor) { 66 const EncodedDataFunctor& encoded_data_functor) {
(...skipping 21 matching lines...) Expand all
83 88
84 template <typename OutputFunctor> 89 template <typename OutputFunctor>
85 void DecodeTest(const std::vector<uint8_t>& data, 90 void DecodeTest(const std::vector<uint8_t>& data,
86 const OutputFunctor& output_functor) { 91 const OutputFunctor& output_functor) {
87 Local<Context> context = deserialization_context(); 92 Local<Context> context = deserialization_context();
88 Context::Scope scope(context); 93 Context::Scope scope(context);
89 TryCatch try_catch(isolate()); 94 TryCatch try_catch(isolate());
90 ValueDeserializer deserializer(isolate(), &data[0], 95 ValueDeserializer deserializer(isolate(), &data[0],
91 static_cast<int>(data.size())); 96 static_cast<int>(data.size()));
92 deserializer.SetSupportsLegacyWireFormat(true); 97 deserializer.SetSupportsLegacyWireFormat(true);
98 BeforeDecode(&deserializer);
93 ASSERT_TRUE(deserializer.ReadHeader().FromMaybe(false)); 99 ASSERT_TRUE(deserializer.ReadHeader().FromMaybe(false));
94 Local<Value> result; 100 Local<Value> result;
95 ASSERT_TRUE(deserializer.ReadValue(context).ToLocal(&result)); 101 ASSERT_TRUE(deserializer.ReadValue(context).ToLocal(&result));
96 ASSERT_FALSE(result.IsEmpty()); 102 ASSERT_FALSE(result.IsEmpty());
97 ASSERT_FALSE(try_catch.HasCaught()); 103 ASSERT_FALSE(try_catch.HasCaught());
98 ASSERT_TRUE( 104 ASSERT_TRUE(
99 context->Global() 105 context->Global()
100 ->CreateDataProperty(context, StringFromUtf8("result"), result) 106 ->CreateDataProperty(context, StringFromUtf8("result"), result)
101 .FromMaybe(false)); 107 .FromMaybe(false));
102 output_functor(result); 108 output_functor(result);
103 ASSERT_FALSE(try_catch.HasCaught()); 109 ASSERT_FALSE(try_catch.HasCaught());
104 } 110 }
105 111
106 template <typename OutputFunctor> 112 template <typename OutputFunctor>
107 void DecodeTestForVersion0(const std::vector<uint8_t>& data, 113 void DecodeTestForVersion0(const std::vector<uint8_t>& data,
108 const OutputFunctor& output_functor) { 114 const OutputFunctor& output_functor) {
109 Local<Context> context = deserialization_context(); 115 Local<Context> context = deserialization_context();
110 Context::Scope scope(context); 116 Context::Scope scope(context);
111 TryCatch try_catch(isolate()); 117 TryCatch try_catch(isolate());
112 ValueDeserializer deserializer(isolate(), &data[0], 118 ValueDeserializer deserializer(isolate(), &data[0],
113 static_cast<int>(data.size())); 119 static_cast<int>(data.size()));
114 deserializer.SetSupportsLegacyWireFormat(true); 120 deserializer.SetSupportsLegacyWireFormat(true);
121 BeforeDecode(&deserializer);
115 ASSERT_TRUE(deserializer.ReadHeader().FromMaybe(false)); 122 ASSERT_TRUE(deserializer.ReadHeader().FromMaybe(false));
116 ASSERT_EQ(0, deserializer.GetWireFormatVersion()); 123 ASSERT_EQ(0, deserializer.GetWireFormatVersion());
117 Local<Value> result; 124 Local<Value> result;
118 ASSERT_TRUE(deserializer.ReadValue(context).ToLocal(&result)); 125 ASSERT_TRUE(deserializer.ReadValue(context).ToLocal(&result));
119 ASSERT_FALSE(result.IsEmpty()); 126 ASSERT_FALSE(result.IsEmpty());
120 ASSERT_FALSE(try_catch.HasCaught()); 127 ASSERT_FALSE(try_catch.HasCaught());
121 ASSERT_TRUE( 128 ASSERT_TRUE(
122 context->Global() 129 context->Global()
123 ->CreateDataProperty(context, StringFromUtf8("result"), result) 130 ->CreateDataProperty(context, StringFromUtf8("result"), result)
124 .FromMaybe(false)); 131 .FromMaybe(false));
125 output_functor(result); 132 output_functor(result);
126 ASSERT_FALSE(try_catch.HasCaught()); 133 ASSERT_FALSE(try_catch.HasCaught());
127 } 134 }
128 135
129 void InvalidDecodeTest(const std::vector<uint8_t>& data) { 136 void InvalidDecodeTest(const std::vector<uint8_t>& data) {
130 Local<Context> context = deserialization_context(); 137 Local<Context> context = deserialization_context();
131 Context::Scope scope(context); 138 Context::Scope scope(context);
132 TryCatch try_catch(isolate()); 139 TryCatch try_catch(isolate());
133 ValueDeserializer deserializer(isolate(), &data[0], 140 ValueDeserializer deserializer(isolate(), &data[0],
134 static_cast<int>(data.size())); 141 static_cast<int>(data.size()));
135 deserializer.SetSupportsLegacyWireFormat(true); 142 deserializer.SetSupportsLegacyWireFormat(true);
143 BeforeDecode(&deserializer);
136 Maybe<bool> header_result = deserializer.ReadHeader(); 144 Maybe<bool> header_result = deserializer.ReadHeader();
137 if (header_result.IsNothing()) return; 145 if (header_result.IsNothing()) return;
138 ASSERT_TRUE(header_result.ToChecked()); 146 ASSERT_TRUE(header_result.ToChecked());
139 ASSERT_TRUE(deserializer.ReadValue(context).IsEmpty()); 147 ASSERT_TRUE(deserializer.ReadValue(context).IsEmpty());
140 } 148 }
141 149
142 Local<Value> EvaluateScriptForInput(const char* utf8_source) { 150 Local<Value> EvaluateScriptForInput(const char* utf8_source) {
143 Local<String> source = StringFromUtf8(utf8_source); 151 Local<String> source = StringFromUtf8(utf8_source);
144 Local<Script> script = 152 Local<Script> script =
145 Script::Compile(serialization_context_, source).ToLocalChecked(); 153 Script::Compile(serialization_context_, source).ToLocalChecked();
(...skipping 1444 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 EXPECT_TRUE( 1598 EXPECT_TRUE(
1591 EvaluateScriptForResultBool("result.a instanceof ArrayBuffer")); 1599 EvaluateScriptForResultBool("result.a instanceof ArrayBuffer"));
1592 EXPECT_TRUE(EvaluateScriptForResultBool("result.a === result.b")); 1600 EXPECT_TRUE(EvaluateScriptForResultBool("result.a === result.b"));
1593 }); 1601 });
1594 } 1602 }
1595 1603
1596 TEST_F(ValueSerializerTest, DecodeInvalidArrayBuffer) { 1604 TEST_F(ValueSerializerTest, DecodeInvalidArrayBuffer) {
1597 InvalidDecodeTest({0xff, 0x09, 0x42, 0xff, 0xff, 0x00}); 1605 InvalidDecodeTest({0xff, 0x09, 0x42, 0xff, 0xff, 0x00});
1598 } 1606 }
1599 1607
1608 // Includes an ArrayBuffer wrapper marked for transfer from the serialization
1609 // context to the deserialization context.
1610 class ValueSerializerTestWithArrayBufferTransfer : public ValueSerializerTest {
1611 protected:
1612 static const size_t kTestByteLength = 4;
1613
1614 ValueSerializerTestWithArrayBufferTransfer() {
1615 {
1616 Context::Scope scope(serialization_context());
1617 input_buffer_ = ArrayBuffer::New(isolate(), nullptr, 0);
1618 input_buffer_->Neuter();
1619 }
1620 {
1621 Context::Scope scope(deserialization_context());
1622 output_buffer_ = ArrayBuffer::New(isolate(), kTestByteLength);
1623 const uint8_t data[kTestByteLength] = {0x00, 0x01, 0x80, 0xff};
1624 memcpy(output_buffer_->GetContents().Data(), data, kTestByteLength);
1625 }
1626 }
1627
1628 const Local<ArrayBuffer>& input_buffer() { return input_buffer_; }
1629 const Local<ArrayBuffer>& output_buffer() { return output_buffer_; }
1630
1631 void BeforeEncode(ValueSerializer* serializer) override {
1632 serializer->TransferArrayBuffer(0, input_buffer_);
1633 }
1634
1635 void BeforeDecode(ValueDeserializer* deserializer) override {
1636 deserializer->TransferArrayBuffer(0, output_buffer_);
1637 }
1638
1639 private:
1640 Local<ArrayBuffer> input_buffer_;
1641 Local<ArrayBuffer> output_buffer_;
1642 };
1643
1644 TEST_F(ValueSerializerTestWithArrayBufferTransfer,
1645 RoundTripArrayBufferTransfer) {
1646 RoundTripTest([this]() { return input_buffer(); },
1647 [this](Local<Value> value) {
1648 ASSERT_TRUE(value->IsArrayBuffer());
1649 EXPECT_EQ(output_buffer(), value);
1650 EXPECT_TRUE(EvaluateScriptForResultBool(
1651 "new Uint8Array(result).toString() === '0,1,128,255'"));
1652 });
1653 RoundTripTest(
1654 [this]() {
1655 Local<Object> object = Object::New(isolate());
1656 EXPECT_TRUE(object
1657 ->CreateDataProperty(serialization_context(),
1658 StringFromUtf8("a"),
1659 input_buffer())
1660 .FromMaybe(false));
1661 EXPECT_TRUE(object
1662 ->CreateDataProperty(serialization_context(),
1663 StringFromUtf8("b"),
1664 input_buffer())
1665 .FromMaybe(false));
1666 return object;
1667 },
1668 [this](Local<Value> value) {
1669 EXPECT_TRUE(
1670 EvaluateScriptForResultBool("result.a instanceof ArrayBuffer"));
1671 EXPECT_TRUE(EvaluateScriptForResultBool("result.a === result.b"));
1672 EXPECT_TRUE(EvaluateScriptForResultBool(
1673 "new Uint8Array(result.a).toString() === '0,1,128,255'"));
1674 });
1675 }
1676
1600 } // namespace 1677 } // namespace
1601 } // namespace v8 1678 } // namespace v8
OLDNEW
« no previous file with comments | « src/value-serializer.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698