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 2577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2588 EvaluateScriptForResultBool("result.a.toString() === '4,5,6'")); | 2588 EvaluateScriptForResultBool("result.a.toString() === '4,5,6'")); |
2589 EXPECT_TRUE(EvaluateScriptForResultBool("result.a === result.b")); | 2589 EXPECT_TRUE(EvaluateScriptForResultBool("result.a === result.b")); |
2590 }); | 2590 }); |
2591 } | 2591 } |
2592 | 2592 |
2593 // It's expected that WebAssembly has more exhaustive tests elsewhere; this | 2593 // It's expected that WebAssembly has more exhaustive tests elsewhere; this |
2594 // mostly checks that the logic to embed it in structured clone serialization | 2594 // mostly checks that the logic to embed it in structured clone serialization |
2595 // works correctly. | 2595 // works correctly. |
2596 | 2596 |
2597 class ValueSerializerTestWithWasm : public ValueSerializerTest { | 2597 class ValueSerializerTestWithWasm : public ValueSerializerTest { |
| 2598 public: |
| 2599 ValueSerializerTestWithWasm() |
| 2600 : deserialize_delegate_(&transfer_modules_), |
| 2601 serialize_delegate_(&transfer_modules_) {} |
| 2602 |
| 2603 void Reset() { |
| 2604 current_serializer_delegate_ = nullptr; |
| 2605 current_deserializer_delegate_ = nullptr; |
| 2606 } |
| 2607 |
| 2608 void EnableTransferSerialization() { |
| 2609 current_serializer_delegate_ = &serialize_delegate_; |
| 2610 } |
| 2611 void EnableTransferDeserialization() { |
| 2612 current_deserializer_delegate_ = &deserialize_delegate_; |
| 2613 } |
| 2614 void AllowInlineWasm(bool value) { |
| 2615 deserialize_delegate_.SetAllowInlineWasm(value); |
| 2616 } |
| 2617 |
2598 protected: | 2618 protected: |
2599 static void SetUpTestCase() { | 2619 static void SetUpTestCase() { |
2600 g_saved_flag = i::FLAG_expose_wasm; | 2620 g_saved_flag = i::FLAG_expose_wasm; |
2601 i::FLAG_expose_wasm = true; | 2621 i::FLAG_expose_wasm = true; |
2602 ValueSerializerTest::SetUpTestCase(); | 2622 ValueSerializerTest::SetUpTestCase(); |
2603 } | 2623 } |
2604 | 2624 |
2605 static void TearDownTestCase() { | 2625 static void TearDownTestCase() { |
2606 ValueSerializerTest::TearDownTestCase(); | 2626 ValueSerializerTest::TearDownTestCase(); |
2607 i::FLAG_expose_wasm = g_saved_flag; | 2627 i::FLAG_expose_wasm = g_saved_flag; |
2608 g_saved_flag = false; | 2628 g_saved_flag = false; |
2609 } | 2629 } |
2610 | 2630 |
| 2631 class SerializeToTransfer : public ValueSerializer::Delegate { |
| 2632 public: |
| 2633 SerializeToTransfer( |
| 2634 std::vector<WasmCompiledModule::TransferrableModule>* modules) |
| 2635 : modules_(modules) {} |
| 2636 Maybe<uint32_t> GetWasmModuleTransferId( |
| 2637 Isolate* isolate, Local<WasmCompiledModule> module) override { |
| 2638 modules_->push_back(module->AsTransferrableModule()); |
| 2639 return Just(static_cast<uint32_t>(modules_->size()) - 1); |
| 2640 } |
| 2641 |
| 2642 void ThrowDataCloneError(Local<String> message) override {} |
| 2643 |
| 2644 private: |
| 2645 std::vector<WasmCompiledModule::TransferrableModule>* modules_; |
| 2646 }; |
| 2647 |
| 2648 class DeserializeToTransfer : public ValueDeserializer::Delegate { |
| 2649 public: |
| 2650 DeserializeToTransfer( |
| 2651 std::vector<WasmCompiledModule::TransferrableModule>* modules) |
| 2652 : modules_(modules) {} |
| 2653 |
| 2654 MaybeLocal<WasmCompiledModule> GetWasmModuleFromId(Isolate* isolate, |
| 2655 uint32_t id) override { |
| 2656 return WasmCompiledModule::FromTransferrableModule(isolate, |
| 2657 modules_->at(id)); |
| 2658 } |
| 2659 bool AllowInlineWasm() const override { return allow_inline_; } |
| 2660 void SetAllowInlineWasm(bool value) { allow_inline_ = value; } |
| 2661 |
| 2662 private: |
| 2663 std::vector<WasmCompiledModule::TransferrableModule>* modules_; |
| 2664 bool allow_inline_ = false; |
| 2665 }; |
| 2666 |
| 2667 ValueSerializer::Delegate* GetSerializerDelegate() override { |
| 2668 return current_serializer_delegate_; |
| 2669 } |
| 2670 ValueDeserializer::Delegate* GetDeserializerDelegate() override { |
| 2671 return current_deserializer_delegate_; |
| 2672 } |
| 2673 |
2611 private: | 2674 private: |
2612 static bool g_saved_flag; | 2675 static bool g_saved_flag; |
| 2676 std::vector<WasmCompiledModule::TransferrableModule> transfer_modules_; |
| 2677 DeserializeToTransfer deserialize_delegate_; |
| 2678 SerializeToTransfer serialize_delegate_; |
| 2679 ValueSerializer::Delegate* current_serializer_delegate_ = nullptr; |
| 2680 ValueDeserializer::Delegate* current_deserializer_delegate_ = nullptr; |
2613 }; | 2681 }; |
2614 | 2682 |
2615 bool ValueSerializerTestWithWasm::g_saved_flag = false; | 2683 bool ValueSerializerTestWithWasm::g_saved_flag = false; |
2616 | 2684 |
2617 // A simple module which exports an "increment" function. | 2685 // A simple module which exports an "increment" function. |
2618 // Copied from test/mjsunit/wasm/incrementer.wasm. | 2686 // Copied from test/mjsunit/wasm/incrementer.wasm. |
2619 const unsigned char kIncrementerWasm[] = { | 2687 const unsigned char kIncrementerWasm[] = { |
2620 0, 97, 115, 109, 1, 0, 0, 0, 1, 6, 1, 96, 1, 127, 1, 127, | 2688 0, 97, 115, 109, 1, 0, 0, 0, 1, 6, 1, 96, 1, 127, 1, 127, |
2621 3, 2, 1, 0, 7, 13, 1, 9, 105, 110, 99, 114, 101, 109, 101, 110, | 2689 3, 2, 1, 0, 7, 13, 1, 9, 105, 110, 99, 114, 101, 109, 101, 110, |
2622 116, 0, 0, 10, 9, 1, 7, 0, 32, 0, 65, 1, 106, 11, | 2690 116, 0, 0, 10, 9, 1, 7, 0, 32, 0, 65, 1, 106, 11, |
2623 }; | 2691 }; |
2624 | 2692 |
2625 TEST_F(ValueSerializerTestWithWasm, RoundTripWasmModule) { | 2693 TEST_F(ValueSerializerTestWithWasm, RoundTripWasmModule) { |
2626 RoundTripTest( | 2694 auto deserialize = [this]() { |
2627 [this]() { | 2695 return WasmCompiledModule::DeserializeOrCompile( |
2628 return WasmCompiledModule::DeserializeOrCompile( | 2696 isolate(), {nullptr, 0}, |
2629 isolate(), {nullptr, 0}, | 2697 {kIncrementerWasm, sizeof(kIncrementerWasm)}) |
2630 {kIncrementerWasm, sizeof(kIncrementerWasm)}) | 2698 .ToLocalChecked(); |
2631 .ToLocalChecked(); | 2699 }; |
2632 }, | 2700 auto passingTest = [this, deserialize]() { |
2633 [this](Local<Value> value) { | 2701 RoundTripTest(deserialize, [this](Local<Value> value) { |
2634 ASSERT_TRUE(value->IsWebAssemblyCompiledModule()); | 2702 ASSERT_TRUE(value->IsWebAssemblyCompiledModule()); |
2635 EXPECT_TRUE(EvaluateScriptForResultBool( | 2703 EXPECT_TRUE(EvaluateScriptForResultBool( |
2636 "new WebAssembly.Instance(result).exports.increment(8) === 9")); | 2704 "new WebAssembly.Instance(result).exports.increment(8) === 9")); |
2637 }); | 2705 }); |
| 2706 }; |
| 2707 |
| 2708 auto failingTest = [this, deserialize]() { |
| 2709 EncodeTest(deserialize, [this](const std::vector<uint8_t>& data) { |
| 2710 InvalidDecodeTest(data); |
| 2711 }); |
| 2712 }; |
| 2713 |
| 2714 // We only want to allow deserialization through |
| 2715 // transferred modules - which requres both serializer |
| 2716 // and deserializer to understand that - or through |
| 2717 // explicitly allowing inlined data, which requires |
| 2718 // deserializer opt-in (we default the serializer to |
| 2719 // inlined data because we don't trust that data on the |
| 2720 // receiving end anyway). |
| 2721 // |
| 2722 // |
| 2723 // Roundtripping works if serializer and |
| 2724 // deserializer both work off transferred data |
| 2725 Reset(); |
| 2726 EnableTransferSerialization(); |
| 2727 EnableTransferDeserialization(); |
| 2728 passingTest(); |
| 2729 // Alternatively, if the deserializer expects inline |
| 2730 // data, and the serializer produces that - which is default |
| 2731 Reset(); |
| 2732 EnableTransferDeserialization(); |
| 2733 AllowInlineWasm(true); |
| 2734 passingTest(); |
| 2735 // By default, the deserializer does not work with inlined |
| 2736 // data |
| 2737 Reset(); |
| 2738 failingTest(); |
| 2739 // Even if the serializer tries transferring, the deserializer |
| 2740 // won't work. |
| 2741 EnableTransferSerialization(); |
| 2742 failingTest(); |
2638 } | 2743 } |
2639 | 2744 |
2640 // As produced around Chrome 56. | 2745 // As produced around Chrome 56. |
2641 const unsigned char kSerializedIncrementerWasm[] = { | 2746 const unsigned char kSerializedIncrementerWasm[] = { |
2642 0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x2d, 0x00, 0x61, 0x73, 0x6d, 0x0d, | 2747 0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x2d, 0x00, 0x61, 0x73, 0x6d, 0x0d, |
2643 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60, 0x01, 0x7f, 0x01, 0x7f, 0x03, | 2748 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60, 0x01, 0x7f, 0x01, 0x7f, 0x03, |
2644 0x02, 0x01, 0x00, 0x07, 0x0d, 0x01, 0x09, 0x69, 0x6e, 0x63, 0x72, 0x65, | 2749 0x02, 0x01, 0x00, 0x07, 0x0d, 0x01, 0x09, 0x69, 0x6e, 0x63, 0x72, 0x65, |
2645 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x0a, 0x08, 0x01, 0x06, 0x00, 0x20, | 2750 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x0a, 0x08, 0x01, 0x06, 0x00, 0x20, |
2646 0x00, 0x41, 0x01, 0x6a, 0xf8, 0x04, 0xa1, 0x06, 0xde, 0xc0, 0xc6, 0x44, | 2751 0x00, 0x41, 0x01, 0x6a, 0xf8, 0x04, 0xa1, 0x06, 0xde, 0xc0, 0xc6, 0x44, |
2647 0x3c, 0x29, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x02, 0x00, 0x00, 0x81, 0x4e, | 2752 0x3c, 0x29, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x02, 0x00, 0x00, 0x81, 0x4e, |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2744 InvalidDecodeTest(raw); | 2849 InvalidDecodeTest(raw); |
2745 } | 2850 } |
2746 | 2851 |
2747 TEST_F(ValueSerializerTestWithWasm, DecodeWasmModuleWithInvalidDataLength) { | 2852 TEST_F(ValueSerializerTestWithWasm, DecodeWasmModuleWithInvalidDataLength) { |
2748 InvalidDecodeTest({0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x7f, 0x00}); | 2853 InvalidDecodeTest({0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x7f, 0x00}); |
2749 InvalidDecodeTest({0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x00, 0x7f}); | 2854 InvalidDecodeTest({0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x00, 0x7f}); |
2750 } | 2855 } |
2751 | 2856 |
2752 } // namespace | 2857 } // namespace |
2753 } // namespace v8 | 2858 } // namespace v8 |
OLD | NEW |