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 #ifndef WASM_RUN_UTILS_H | 5 #ifndef WASM_RUN_UTILS_H |
6 #define WASM_RUN_UTILS_H | 6 #define WASM_RUN_UTILS_H |
7 | 7 |
| 8 #include <setjmp.h> |
8 #include <stdint.h> | 9 #include <stdint.h> |
9 #include <stdlib.h> | 10 #include <stdlib.h> |
10 #include <string.h> | 11 #include <string.h> |
11 #include <memory> | 12 #include <memory> |
12 | 13 |
13 #include "src/base/utils/random-number-generator.h" | 14 #include "src/base/utils/random-number-generator.h" |
14 #include "src/zone/accounting-allocator.h" | 15 #include "src/zone/accounting-allocator.h" |
15 | 16 |
16 #include "src/compiler/compiler-source-position-table.h" | 17 #include "src/compiler/compiler-source-position-table.h" |
17 #include "src/compiler/graph-visualizer.h" | 18 #include "src/compiler/graph-visualizer.h" |
18 #include "src/compiler/int64-lowering.h" | 19 #include "src/compiler/int64-lowering.h" |
19 #include "src/compiler/js-graph.h" | 20 #include "src/compiler/js-graph.h" |
20 #include "src/compiler/node.h" | 21 #include "src/compiler/node.h" |
21 #include "src/compiler/pipeline.h" | 22 #include "src/compiler/pipeline.h" |
22 #include "src/compiler/wasm-compiler.h" | 23 #include "src/compiler/wasm-compiler.h" |
23 #include "src/compiler/zone-stats.h" | 24 #include "src/compiler/zone-stats.h" |
24 #include "src/wasm/ast-decoder.h" | 25 #include "src/wasm/ast-decoder.h" |
| 26 #include "src/wasm/wasm-external-refs.h" |
25 #include "src/wasm/wasm-interpreter.h" | 27 #include "src/wasm/wasm-interpreter.h" |
26 #include "src/wasm/wasm-js.h" | 28 #include "src/wasm/wasm-js.h" |
27 #include "src/wasm/wasm-macro-gen.h" | 29 #include "src/wasm/wasm-macro-gen.h" |
28 #include "src/wasm/wasm-module.h" | 30 #include "src/wasm/wasm-module.h" |
29 #include "src/wasm/wasm-objects.h" | 31 #include "src/wasm/wasm-objects.h" |
30 #include "src/wasm/wasm-opcodes.h" | 32 #include "src/wasm/wasm-opcodes.h" |
31 | 33 |
32 #include "src/zone/zone.h" | 34 #include "src/zone/zone.h" |
33 | 35 |
34 #include "test/cctest/cctest.h" | 36 #include "test/cctest/cctest.h" |
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 void SetModuleContext() { | 606 void SetModuleContext() { |
605 if (!testing_module_->instance->context.is_null()) { | 607 if (!testing_module_->instance->context.is_null()) { |
606 CHECK(testing_module_->instance->context.is_identical_to( | 608 CHECK(testing_module_->instance->context.is_identical_to( |
607 main_isolate()->native_context())); | 609 main_isolate()->native_context())); |
608 return; | 610 return; |
609 } | 611 } |
610 testing_module_->instance->context = main_isolate()->native_context(); | 612 testing_module_->instance->context = main_isolate()->native_context(); |
611 } | 613 } |
612 }; | 614 }; |
613 | 615 |
| 616 template <typename ReturnType> |
| 617 union ReturnTypeUnion { |
| 618 ReturnType value; |
| 619 uint64_t trap; |
| 620 }; |
| 621 |
614 // A helper class to build graphs from Wasm bytecode, generate machine | 622 // A helper class to build graphs from Wasm bytecode, generate machine |
615 // code, and run that code. | 623 // code, and run that code. |
616 template <typename ReturnType> | 624 template <typename ReturnType> |
617 class WasmRunner { | 625 class WasmRunner { |
618 public: | 626 public: |
619 WasmRunner(WasmExecutionMode execution_mode, | 627 WasmRunner(WasmExecutionMode execution_mode, |
620 MachineType p0 = MachineType::None(), | 628 MachineType p0 = MachineType::None(), |
621 MachineType p1 = MachineType::None(), | 629 MachineType p1 = MachineType::None(), |
622 MachineType p2 = MachineType::None(), | 630 MachineType p2 = MachineType::None(), |
623 MachineType p3 = MachineType::None()) | 631 MachineType p3 = MachineType::None()) |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
716 template <typename P0, typename P1, typename P2> | 724 template <typename P0, typename P1, typename P2> |
717 ReturnType Call(P0 p0, P1 p1, P2 p2) { | 725 ReturnType Call(P0 p0, P1 p1, P2 p2) { |
718 if (interpret()) { | 726 if (interpret()) { |
719 WasmVal args[] = {WasmVal(p0), WasmVal(p1), WasmVal(p2)}; | 727 WasmVal args[] = {WasmVal(p0), WasmVal(p1), WasmVal(p2)}; |
720 return CallInterpreter(ArrayVector(args)); | 728 return CallInterpreter(ArrayVector(args)); |
721 } else { | 729 } else { |
722 return Call(p0, p1, p2, 0); | 730 return Call(p0, p1, p2, 0); |
723 } | 731 } |
724 } | 732 } |
725 | 733 |
| 734 static jmp_buf jump_buffer; |
| 735 static int jump_value; |
| 736 static ReturnTypeUnion<ReturnType> return_value; |
| 737 |
| 738 template <typename P0, typename P1, typename P2, typename P3> |
| 739 void DoCall(P0 p0, P1 p1, P2 p2, P3 p3) { |
| 740 auto trap_callback = []() { |
| 741 WasmRunner<ReturnType>::return_value.trap = 0xdeadbeefdeadbeef; |
| 742 longjmp(WasmRunner<ReturnType>::jump_buffer, 1); |
| 743 }; |
| 744 set_trap_callback_for_testing(trap_callback); |
| 745 CodeRunner<int32_t> runner(CcTest::InitIsolateOnce(), |
| 746 wrapper_.GetWrapperCode(), wrapper_.signature()); |
| 747 |
| 748 int32_t result = runner.Call<void*, void*, void*, void*, void*>( |
| 749 &p0, &p1, &p2, &p3, &WasmRunner<ReturnType>::return_value.value); |
| 750 CHECK_EQ(WASM_WRAPPER_RETURN_VALUE, result); |
| 751 } |
| 752 |
726 template <typename P0, typename P1, typename P2, typename P3> | 753 template <typename P0, typename P1, typename P2, typename P3> |
727 ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) { | 754 ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) { |
728 if (interpret()) { | 755 if (interpret()) { |
729 WasmVal args[] = {WasmVal(p0), WasmVal(p1), WasmVal(p2), WasmVal(p3)}; | 756 WasmVal args[] = {WasmVal(p0), WasmVal(p1), WasmVal(p2), WasmVal(p3)}; |
730 return CallInterpreter(ArrayVector(args)); | 757 return CallInterpreter(ArrayVector(args)); |
731 } else { | 758 } else { |
732 CodeRunner<int32_t> runner(CcTest::InitIsolateOnce(), | 759 // Use setjmp/longjmp to deal with traps in WebAssembly code. |
733 wrapper_.GetWrapperCode(), | 760 WasmRunner<ReturnType>::jump_value = |
734 wrapper_.signature()); | 761 setjmp(WasmRunner<ReturnType>::jump_buffer); |
735 ReturnType return_value; | 762 if (!WasmRunner<ReturnType>::jump_value) { |
736 int32_t result = runner.Call<void*, void*, void*, void*, void*>( | 763 DoCall(p0, p1, p2, p3); |
737 &p0, &p1, &p2, &p3, &return_value); | 764 } |
738 CHECK_EQ(WASM_WRAPPER_RETURN_VALUE, result); | 765 set_trap_callback_for_testing(nullptr); |
739 return return_value; | 766 return WasmRunner<ReturnType>::return_value.value; |
740 } | 767 } |
741 } | 768 } |
742 | 769 |
743 ReturnType CallInterpreter(Vector<WasmVal> args) { | 770 ReturnType CallInterpreter(Vector<WasmVal> args) { |
744 CHECK_EQ(args.length(), | 771 CHECK_EQ(args.length(), |
745 static_cast<int>(compiler_.function_->sig->parameter_count())); | 772 static_cast<int>(compiler_.function_->sig->parameter_count())); |
746 WasmInterpreter::Thread* thread = interpreter()->GetThread(0); | 773 WasmInterpreter::Thread* thread = interpreter()->GetThread(0); |
747 thread->Reset(); | 774 thread->Reset(); |
748 thread->PushFrame(compiler_.function_, args.start()); | 775 thread->PushFrame(compiler_.function_, args.start()); |
749 if (thread->Run() == WasmInterpreter::FINISHED) { | 776 if (thread->Run() == WasmInterpreter::FINISHED) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 static size_t GetParameterCount(MachineType p0, MachineType p1, | 809 static size_t GetParameterCount(MachineType p0, MachineType p1, |
783 MachineType p2, MachineType p3) { | 810 MachineType p2, MachineType p3) { |
784 if (p0 == MachineType::None()) return 0; | 811 if (p0 == MachineType::None()) return 0; |
785 if (p1 == MachineType::None()) return 1; | 812 if (p1 == MachineType::None()) return 1; |
786 if (p2 == MachineType::None()) return 2; | 813 if (p2 == MachineType::None()) return 2; |
787 if (p3 == MachineType::None()) return 3; | 814 if (p3 == MachineType::None()) return 3; |
788 return 4; | 815 return 4; |
789 } | 816 } |
790 }; | 817 }; |
791 | 818 |
| 819 template <typename ReturnType> |
| 820 jmp_buf WasmRunner<ReturnType>::jump_buffer; |
| 821 template <typename ReturnType> |
| 822 int WasmRunner<ReturnType>::jump_value; |
| 823 template <typename ReturnType> |
| 824 ReturnTypeUnion<ReturnType> WasmRunner<ReturnType>::return_value; |
| 825 |
792 // A macro to define tests that run in different engine configurations. | 826 // A macro to define tests that run in different engine configurations. |
793 #define WASM_EXEC_TEST(name) \ | 827 #define WASM_EXEC_TEST(name) \ |
794 void RunWasm_##name(WasmExecutionMode execution_mode); \ | 828 void RunWasm_##name(WasmExecutionMode execution_mode); \ |
795 TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \ | 829 TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \ |
796 TEST(RunWasmInterpreted_##name) { RunWasm_##name(kExecuteInterpreted); } \ | 830 TEST(RunWasmInterpreted_##name) { RunWasm_##name(kExecuteInterpreted); } \ |
797 void RunWasm_##name(WasmExecutionMode execution_mode) | 831 void RunWasm_##name(WasmExecutionMode execution_mode) |
798 | 832 |
| 833 #define WASM_EXEC_TEST_WITH_TRAP(name) \ |
| 834 void RunWasm_##name(WasmExecutionMode execution_mode); \ |
| 835 TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \ |
| 836 void RunWasm_##name(WasmExecutionMode execution_mode); \ |
| 837 TEST(RunWasmCompiledWithTrapIf_##name) { \ |
| 838 bool trap_if = FLAG_wasm_trap_if; \ |
| 839 FLAG_wasm_trap_if = true; \ |
| 840 RunWasm_##name(kExecuteCompiled); \ |
| 841 FLAG_wasm_trap_if = trap_if; \ |
| 842 } \ |
| 843 TEST(RunWasmInterpreted_##name) { RunWasm_##name(kExecuteInterpreted); } \ |
| 844 void RunWasm_##name(WasmExecutionMode execution_mode) |
| 845 |
799 #define WASM_EXEC_COMPILED_TEST(name) \ | 846 #define WASM_EXEC_COMPILED_TEST(name) \ |
800 void RunWasm_##name(WasmExecutionMode execution_mode); \ | 847 void RunWasm_##name(WasmExecutionMode execution_mode); \ |
801 TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \ | 848 TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \ |
802 void RunWasm_##name(WasmExecutionMode execution_mode) | 849 void RunWasm_##name(WasmExecutionMode execution_mode) |
803 | 850 |
804 } // namespace | 851 } // namespace |
805 | 852 |
806 #endif | 853 #endif |
OLD | NEW |