Index: test/unittests/value-serializer-unittest.cc |
diff --git a/test/unittests/value-serializer-unittest.cc b/test/unittests/value-serializer-unittest.cc |
index 9f49c6498af92304c13cef6577306a4962111946..c0037efb01709e9c401992d89292422494bf18c1 100644 |
--- a/test/unittests/value-serializer-unittest.cc |
+++ b/test/unittests/value-serializer-unittest.cc |
@@ -74,9 +74,6 @@ |
return deserialization_context_; |
} |
- bool ExpectInlineWasm() const { return expect_inline_wasm_; } |
- void SetExpectInlineWasm(bool value) { expect_inline_wasm_ = value; } |
- |
// Overridden in more specific fixtures. |
virtual ValueSerializer::Delegate* GetSerializerDelegate() { return nullptr; } |
virtual void BeforeEncode(ValueSerializer*) {} |
@@ -175,7 +172,6 @@ |
static_cast<int>(data.size()), |
GetDeserializerDelegate()); |
deserializer.SetSupportsLegacyWireFormat(true); |
- deserializer.SetExpectInlineWasm(ExpectInlineWasm()); |
BeforeDecode(&deserializer); |
ASSERT_TRUE(deserializer.ReadHeader(context).FromMaybe(false)); |
Local<Value> result; |
@@ -200,7 +196,6 @@ |
static_cast<int>(data.size()), |
GetDeserializerDelegate()); |
deserializer.SetSupportsLegacyWireFormat(true); |
- deserializer.SetExpectInlineWasm(ExpectInlineWasm()); |
BeforeDecode(&deserializer); |
ASSERT_TRUE(deserializer.ReadHeader(context).FromMaybe(false)); |
ASSERT_EQ(0u, deserializer.GetWireFormatVersion()); |
@@ -224,7 +219,6 @@ |
static_cast<int>(data.size()), |
GetDeserializerDelegate()); |
deserializer.SetSupportsLegacyWireFormat(true); |
- deserializer.SetExpectInlineWasm(ExpectInlineWasm()); |
BeforeDecode(&deserializer); |
Maybe<bool> header_result = deserializer.ReadHeader(context); |
if (header_result.IsNothing()) { |
@@ -281,7 +275,6 @@ |
Local<Context> deserialization_context_; |
Local<FunctionTemplate> host_object_constructor_template_; |
i::Isolate* isolate_; |
- bool expect_inline_wasm_ = false; |
DISALLOW_COPY_AND_ASSIGN(ValueSerializerTest); |
}; |
@@ -2601,6 +2594,26 @@ |
// mostly checks that the logic to embed it in structured clone serialization |
// works correctly. |
+class ValueSerializerTestWithWasm : public ValueSerializerTest { |
+ protected: |
+ static void SetUpTestCase() { |
+ g_saved_flag = i::FLAG_expose_wasm; |
+ i::FLAG_expose_wasm = true; |
+ ValueSerializerTest::SetUpTestCase(); |
+ } |
+ |
+ static void TearDownTestCase() { |
+ ValueSerializerTest::TearDownTestCase(); |
+ i::FLAG_expose_wasm = g_saved_flag; |
+ g_saved_flag = false; |
+ } |
+ |
+ private: |
+ static bool g_saved_flag; |
+}; |
+ |
+bool ValueSerializerTestWithWasm::g_saved_flag = false; |
+ |
// A simple module which exports an "increment" function. |
// Copied from test/mjsunit/wasm/incrementer.wasm. |
const unsigned char kIncrementerWasm[] = { |
@@ -2609,286 +2622,18 @@ |
116, 0, 0, 10, 9, 1, 7, 0, 32, 0, 65, 1, 106, 11, |
}; |
-class ValueSerializerTestWithWasm : public ValueSerializerTest { |
- public: |
- static const char* kUnsupportedSerialization; |
- |
- ValueSerializerTestWithWasm() |
- : serialize_delegate_(&transfer_modules_), |
- deserialize_delegate_(&transfer_modules_) {} |
- |
- void Reset() { |
- current_serializer_delegate_ = nullptr; |
- transfer_modules_.clear(); |
- SetExpectInlineWasm(false); |
- } |
- |
- void EnableTransferSerialization() { |
- current_serializer_delegate_ = &serialize_delegate_; |
- } |
- |
- void EnableTransferDeserialization() { |
- current_deserializer_delegate_ = &deserialize_delegate_; |
- } |
- |
- void EnableThrowingSerializer() { |
- current_serializer_delegate_ = &throwing_serializer_; |
- } |
- |
- void EnableDefaultDeserializer() { |
- current_deserializer_delegate_ = &default_deserializer_; |
- } |
- |
- protected: |
- static void SetUpTestCase() { |
- g_saved_flag = i::FLAG_expose_wasm; |
- i::FLAG_expose_wasm = true; |
- ValueSerializerTest::SetUpTestCase(); |
- } |
- |
- static void TearDownTestCase() { |
- ValueSerializerTest::TearDownTestCase(); |
- i::FLAG_expose_wasm = g_saved_flag; |
- g_saved_flag = false; |
- } |
- |
- class ThrowingSerializer : public ValueSerializer::Delegate { |
- public: |
- Maybe<uint32_t> GetWasmModuleTransferId( |
- Isolate* isolate, Local<WasmCompiledModule> module) override { |
- isolate->ThrowException(Exception::Error( |
- String::NewFromOneByte( |
- isolate, |
- reinterpret_cast<const uint8_t*>(kUnsupportedSerialization), |
- NewStringType::kNormal) |
- .ToLocalChecked())); |
- return Nothing<uint32_t>(); |
- } |
- |
- void ThrowDataCloneError(Local<String> message) override { UNREACHABLE(); } |
- }; |
- |
- class SerializeToTransfer : public ValueSerializer::Delegate { |
- public: |
- SerializeToTransfer( |
- std::vector<WasmCompiledModule::TransferrableModule>* modules) |
- : modules_(modules) {} |
- Maybe<uint32_t> GetWasmModuleTransferId( |
- Isolate* isolate, Local<WasmCompiledModule> module) override { |
- modules_->push_back(module->GetTransferrableModule()); |
- return Just(static_cast<uint32_t>(modules_->size()) - 1); |
- } |
- |
- void ThrowDataCloneError(Local<String> message) override { UNREACHABLE(); } |
- |
- private: |
- std::vector<WasmCompiledModule::TransferrableModule>* modules_; |
- }; |
- |
- class DeserializeFromTransfer : public ValueDeserializer::Delegate { |
- public: |
- DeserializeFromTransfer( |
- std::vector<WasmCompiledModule::TransferrableModule>* modules) |
- : modules_(modules) {} |
- |
- MaybeLocal<WasmCompiledModule> GetWasmModuleFromId(Isolate* isolate, |
- uint32_t id) override { |
- return WasmCompiledModule::FromTransferrableModule(isolate, |
- modules_->at(id)); |
- } |
- |
- private: |
- std::vector<WasmCompiledModule::TransferrableModule>* modules_; |
- }; |
- |
- ValueSerializer::Delegate* GetSerializerDelegate() override { |
- return current_serializer_delegate_; |
- } |
- |
- ValueDeserializer::Delegate* GetDeserializerDelegate() override { |
- return current_deserializer_delegate_; |
- } |
- |
- Local<WasmCompiledModule> MakeWasm() { |
- return WasmCompiledModule::DeserializeOrCompile( |
- isolate(), {nullptr, 0}, |
- {kIncrementerWasm, sizeof(kIncrementerWasm)}) |
- .ToLocalChecked(); |
- } |
- |
- void ExpectPass() { |
- RoundTripTest( |
- [this]() { return MakeWasm(); }, |
- [this](Local<Value> value) { |
- ASSERT_TRUE(value->IsWebAssemblyCompiledModule()); |
- EXPECT_TRUE(EvaluateScriptForResultBool( |
- "new WebAssembly.Instance(result).exports.increment(8) === 9")); |
- }); |
- } |
- |
- void ExpectFail() { |
- EncodeTest( |
- [this]() { return MakeWasm(); }, |
- [this](const std::vector<uint8_t>& data) { InvalidDecodeTest(data); }); |
- } |
- |
- Local<Value> GetComplexObjectWithDuplicate() { |
- Local<Value> wasm_module = MakeWasm(); |
- serialization_context() |
- ->Global() |
- ->CreateDataProperty(serialization_context(), |
- StringFromUtf8("wasm_module"), wasm_module) |
- .FromMaybe(false); |
- Local<Script> script = |
- Script::Compile( |
- serialization_context(), |
- StringFromUtf8("({mod1: wasm_module, num: 2, mod2: wasm_module})")) |
+TEST_F(ValueSerializerTestWithWasm, RoundTripWasmModule) { |
+ RoundTripTest( |
+ [this]() { |
+ return WasmCompiledModule::DeserializeOrCompile( |
+ isolate(), {nullptr, 0}, |
+ {kIncrementerWasm, sizeof(kIncrementerWasm)}) |
.ToLocalChecked(); |
- return script->Run(serialization_context()).ToLocalChecked(); |
- } |
- |
- void VerifyComplexObject(Local<Value> value) { |
- ASSERT_TRUE(value->IsObject()); |
- EXPECT_TRUE(EvaluateScriptForResultBool( |
- "result.mod1 instanceof WebAssembly.Module")); |
- EXPECT_TRUE(EvaluateScriptForResultBool( |
- "result.mod2 instanceof WebAssembly.Module")); |
- EXPECT_TRUE(EvaluateScriptForResultBool("result.num === 2")); |
- } |
- |
- Local<Value> GetComplexObjectWithMany() { |
- Local<Value> wasm_module1 = MakeWasm(); |
- Local<Value> wasm_module2 = MakeWasm(); |
- serialization_context() |
- ->Global() |
- ->CreateDataProperty(serialization_context(), |
- StringFromUtf8("wasm_module1"), wasm_module1) |
- .FromMaybe(false); |
- serialization_context() |
- ->Global() |
- ->CreateDataProperty(serialization_context(), |
- StringFromUtf8("wasm_module2"), wasm_module2) |
- .FromMaybe(false); |
- Local<Script> script = |
- Script::Compile( |
- serialization_context(), |
- StringFromUtf8( |
- "({mod1: wasm_module1, num: 2, mod2: wasm_module2})")) |
- .ToLocalChecked(); |
- return script->Run(serialization_context()).ToLocalChecked(); |
- } |
- |
- private: |
- static bool g_saved_flag; |
- std::vector<WasmCompiledModule::TransferrableModule> transfer_modules_; |
- SerializeToTransfer serialize_delegate_; |
- DeserializeFromTransfer deserialize_delegate_; |
- ValueSerializer::Delegate* current_serializer_delegate_ = nullptr; |
- ValueDeserializer::Delegate* current_deserializer_delegate_ = nullptr; |
- ThrowingSerializer throwing_serializer_; |
- ValueDeserializer::Delegate default_deserializer_; |
-}; |
- |
-bool ValueSerializerTestWithWasm::g_saved_flag = false; |
-const char* ValueSerializerTestWithWasm::kUnsupportedSerialization = |
- "Wasm Serialization Not Supported"; |
- |
-// The default implementation of the serialization |
-// delegate throws when trying to serialize wasm. The |
-// embedder must decide serialization policy. |
-TEST_F(ValueSerializerTestWithWasm, DefaultSerializationDelegate) { |
- EnableThrowingSerializer(); |
- InvalidEncodeTest( |
- [this]() { return MakeWasm(); }, |
- [](Local<Message> message) { |
- size_t msg_len = static_cast<size_t>(message->Get()->Length()); |
- std::unique_ptr<char[]> buff(new char[msg_len + 1]); |
- message->Get()->WriteOneByte(reinterpret_cast<uint8_t*>(buff.get())); |
- // the message ends with the custom error string |
- size_t custom_msg_len = strlen(kUnsupportedSerialization); |
- ASSERT_GE(msg_len, custom_msg_len); |
- size_t start_pos = msg_len - custom_msg_len; |
- ASSERT_EQ(strcmp(&buff.get()[start_pos], kUnsupportedSerialization), 0); |
- }); |
-} |
- |
-// The default deserializer throws if wasm transfer is attempted |
-TEST_F(ValueSerializerTestWithWasm, DefaultDeserializationDelegate) { |
- EnableTransferSerialization(); |
- EnableDefaultDeserializer(); |
- EncodeTest( |
- [this]() { return MakeWasm(); }, |
- [this](const std::vector<uint8_t>& data) { InvalidDecodeTest(data); }); |
-} |
- |
-// We only want to allow deserialization through |
-// transferred modules - which requres both serializer |
-// and deserializer to understand that - or through |
-// explicitly allowing inlined data, which requires |
-// deserializer opt-in (we default the serializer to |
-// inlined data because we don't trust that data on the |
-// receiving end anyway). |
- |
-TEST_F(ValueSerializerTestWithWasm, RoundtripWasmTransfer) { |
- EnableTransferSerialization(); |
- EnableTransferDeserialization(); |
- ExpectPass(); |
-} |
- |
-TEST_F(ValueSerializerTestWithWasm, RountripWasmInline) { |
- SetExpectInlineWasm(true); |
- ExpectPass(); |
-} |
- |
-TEST_F(ValueSerializerTestWithWasm, CannotDeserializeWasmInlineData) { |
- ExpectFail(); |
-} |
- |
-TEST_F(ValueSerializerTestWithWasm, CannotTransferWasmWhenExpectingInline) { |
- EnableTransferSerialization(); |
- SetExpectInlineWasm(true); |
- ExpectFail(); |
-} |
- |
-TEST_F(ValueSerializerTestWithWasm, ComplexObjectDuplicateTransfer) { |
- EnableTransferSerialization(); |
- EnableTransferDeserialization(); |
- RoundTripTest( |
- [this]() { return GetComplexObjectWithDuplicate(); }, |
- [this](Local<Value> value) { |
- VerifyComplexObject(value); |
- EXPECT_TRUE(EvaluateScriptForResultBool("result.mod1 === result.mod2")); |
- }); |
-} |
- |
-TEST_F(ValueSerializerTestWithWasm, ComplexObjectDuplicateInline) { |
- SetExpectInlineWasm(true); |
- RoundTripTest( |
- [this]() { return GetComplexObjectWithDuplicate(); }, |
- [this](Local<Value> value) { |
- VerifyComplexObject(value); |
- EXPECT_TRUE(EvaluateScriptForResultBool("result.mod1 === result.mod2")); |
- }); |
-} |
- |
-TEST_F(ValueSerializerTestWithWasm, ComplexObjectWithManyTransfer) { |
- EnableTransferSerialization(); |
- EnableTransferDeserialization(); |
- RoundTripTest( |
- [this]() { return GetComplexObjectWithMany(); }, |
- [this](Local<Value> value) { |
- VerifyComplexObject(value); |
- EXPECT_TRUE(EvaluateScriptForResultBool("result.mod1 != result.mod2")); |
- }); |
-} |
- |
-TEST_F(ValueSerializerTestWithWasm, ComplexObjectWithManyInline) { |
- SetExpectInlineWasm(true); |
- RoundTripTest( |
- [this]() { return GetComplexObjectWithMany(); }, |
- [this](Local<Value> value) { |
- VerifyComplexObject(value); |
- EXPECT_TRUE(EvaluateScriptForResultBool("result.mod1 != result.mod2")); |
+ }, |
+ [this](Local<Value> value) { |
+ ASSERT_TRUE(value->IsWebAssemblyCompiledModule()); |
+ EXPECT_TRUE(EvaluateScriptForResultBool( |
+ "new WebAssembly.Instance(result).exports.increment(8) === 9")); |
}); |
} |