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

Side by Side Diff: test/cctest/wasm/wasm-run-utils.h

Issue 2685583003: [wasm] Do not use setjmp/longjmp in cctests. (Closed)
Patch Set: Change comments Created 3 years, 10 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 | « test/cctest/wasm/test-run-wasm-64.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 #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 <setjmp.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 #include <stdlib.h> 10 #include <stdlib.h>
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 Zone zone_; 734 Zone zone_;
735 TestingModule module_; 735 TestingModule module_;
736 std::vector<std::unique_ptr<WasmFunctionCompiler>> functions_; 736 std::vector<std::unique_ptr<WasmFunctionCompiler>> functions_;
737 WasmFunctionWrapper wrapper_; 737 WasmFunctionWrapper wrapper_;
738 bool compiled_ = false; 738 bool compiled_ = false;
739 bool possible_nondeterminism_ = false; 739 bool possible_nondeterminism_ = false;
740 740
741 bool interpret() { return module_.execution_mode() == kExecuteInterpreted; } 741 bool interpret() { return module_.execution_mode() == kExecuteInterpreted; }
742 742
743 public: 743 public:
744 // This field has to be static. Otherwise, gcc complains about the using in 744 // This field has to be static. Otherwise, gcc complains about the use in
745 // the lambda context below. 745 // the lambda context below.
746 static jmp_buf jump_buffer; 746 static bool trap_happened;
747 }; 747 };
748 748
749 template <typename ReturnType, typename... ParamTypes> 749 template <typename ReturnType, typename... ParamTypes>
750 class WasmRunner : public WasmRunnerBase { 750 class WasmRunner : public WasmRunnerBase {
751 public: 751 public:
752 explicit WasmRunner(WasmExecutionMode execution_mode, 752 explicit WasmRunner(WasmExecutionMode execution_mode,
753 const char* main_fn_name = "main") 753 const char* main_fn_name = "main")
754 : WasmRunnerBase(execution_mode, sizeof...(ParamTypes)) { 754 : WasmRunnerBase(execution_mode, sizeof...(ParamTypes)) {
755 NewFunction<ReturnType, ParamTypes...>(main_fn_name); 755 NewFunction<ReturnType, ParamTypes...>(main_fn_name);
756 if (!interpret()) { 756 if (!interpret()) {
757 wrapper_.Init<ReturnType, ParamTypes...>(functions_[0]->descriptor()); 757 wrapper_.Init<ReturnType, ParamTypes...>(functions_[0]->descriptor());
758 } 758 }
759 } 759 }
760 760
761 ReturnType Call(ParamTypes... p) { 761 ReturnType Call(ParamTypes... p) {
762 DCHECK(compiled_); 762 DCHECK(compiled_);
763 if (interpret()) return CallInterpreter(p...); 763 if (interpret()) return CallInterpreter(p...);
764 764
765 // Use setjmp/longjmp to deal with traps in WebAssembly code.
766 ReturnType return_value = static_cast<ReturnType>(0xdeadbeefdeadbeef); 765 ReturnType return_value = static_cast<ReturnType>(0xdeadbeefdeadbeef);
767 static int setjmp_ret; 766 WasmRunnerBase::trap_happened = false;
768 setjmp_ret = setjmp(WasmRunnerBase::jump_buffer); 767 auto trap_callback = []() -> void {
769 // setjmp returns 0 on the first return, 1 (passed to longjmp) after trap. 768 WasmRunnerBase::trap_happened = true;
770 if (setjmp_ret == 0) { 769 set_trap_callback_for_testing(nullptr);
771 DoCall(static_cast<void*>(&p)..., static_cast<void*>(&return_value)); 770 };
772 } 771 set_trap_callback_for_testing(trap_callback);
773 return return_value; 772
773 wrapper_.SetInnerCode(
774 module_.GetFunctionCode(functions_[0]->function_index()));
775 CodeRunner<int32_t> runner(CcTest::InitIsolateOnce(),
776 wrapper_.GetWrapperCode(), wrapper_.signature());
777 int32_t result = runner.Call(static_cast<void*>(&p)...,
778 static_cast<void*>(&return_value));
779 CHECK_EQ(WASM_WRAPPER_RETURN_VALUE, result);
780 return WasmRunnerBase::trap_happened
781 ? static_cast<ReturnType>(0xdeadbeefdeadbeef)
782 : return_value;
774 } 783 }
775 784
776 ReturnType CallInterpreter(ParamTypes... p) { 785 ReturnType CallInterpreter(ParamTypes... p) {
777 WasmInterpreter::Thread* thread = interpreter()->GetThread(0); 786 WasmInterpreter::Thread* thread = interpreter()->GetThread(0);
778 thread->Reset(); 787 thread->Reset();
779 std::array<WasmVal, sizeof...(p)> args{{WasmVal(p)...}}; 788 std::array<WasmVal, sizeof...(p)> args{{WasmVal(p)...}};
780 thread->PushFrame(function(), args.data()); 789 thread->PushFrame(function(), args.data());
781 if (thread->Run() == WasmInterpreter::FINISHED) { 790 if (thread->Run() == WasmInterpreter::FINISHED) {
782 WasmVal val = thread->GetReturnValue(); 791 WasmVal val = thread->GetReturnValue();
783 possible_nondeterminism_ |= thread->PossibleNondeterminism(); 792 possible_nondeterminism_ |= thread->PossibleNondeterminism();
784 return val.to<ReturnType>(); 793 return val.to<ReturnType>();
785 } else if (thread->state() == WasmInterpreter::TRAPPED) { 794 } else if (thread->state() == WasmInterpreter::TRAPPED) {
786 // TODO(titzer): return the correct trap code 795 // TODO(titzer): return the correct trap code
787 int64_t result = 0xdeadbeefdeadbeef; 796 int64_t result = 0xdeadbeefdeadbeef;
788 return static_cast<ReturnType>(result); 797 return static_cast<ReturnType>(result);
789 } else { 798 } else {
790 // TODO(titzer): falling off end 799 // TODO(titzer): falling off end
791 return ReturnType{0}; 800 return ReturnType{0};
792 } 801 }
793 } 802 }
794
795 private:
796 // Don't inline this function. The setjmp above should be followed immediately
797 // by a call.
798 template <typename... Ptrs>
799 V8_NOINLINE void DoCall(Ptrs... ptrs) {
800 auto trap_callback = []() -> void {
801 set_trap_callback_for_testing(nullptr);
802 longjmp(WasmRunnerBase::jump_buffer, 1);
803 };
804 set_trap_callback_for_testing(trap_callback);
805
806 wrapper_.SetInnerCode(
807 module_.GetFunctionCode(functions_[0]->function_index()));
808 CodeRunner<int32_t> runner(CcTest::InitIsolateOnce(),
809 wrapper_.GetWrapperCode(), wrapper_.signature());
810 int32_t result = runner.Call(ptrs...);
811 // If we arrive here, no trap happened.
812 CHECK_EQ(WASM_WRAPPER_RETURN_VALUE, result);
813 }
814 }; 803 };
815 804
816 // Declare static variable. 805 // Declare static variable.
817 jmp_buf WasmRunnerBase::jump_buffer; 806 bool WasmRunnerBase::trap_happened;
818 807
819 // A macro to define tests that run in different engine configurations. 808 // A macro to define tests that run in different engine configurations.
820 #define WASM_EXEC_TEST(name) \ 809 #define WASM_EXEC_TEST(name) \
821 void RunWasm_##name(WasmExecutionMode execution_mode); \ 810 void RunWasm_##name(WasmExecutionMode execution_mode); \
822 TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \ 811 TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \
823 TEST(RunWasmInterpreted_##name) { RunWasm_##name(kExecuteInterpreted); } \ 812 TEST(RunWasmInterpreted_##name) { RunWasm_##name(kExecuteInterpreted); } \
824 void RunWasm_##name(WasmExecutionMode execution_mode) 813 void RunWasm_##name(WasmExecutionMode execution_mode)
825 814
826 #define WASM_EXEC_TEST_WITH_TRAP(name) \ 815 #define WASM_EXEC_TEST_WITH_TRAP(name) \
827 void RunWasm_##name(WasmExecutionMode execution_mode); \ 816 void RunWasm_##name(WasmExecutionMode execution_mode); \
828 TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \ 817 TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \
829 void RunWasm_##name(WasmExecutionMode execution_mode); \ 818 void RunWasm_##name(WasmExecutionMode execution_mode); \
830 TEST(RunWasmCompiledWithoutTrapIf_##name) { \ 819 TEST(RunWasmCompiledWithoutTrapIf_##name) { \
831 bool trap_if = FLAG_wasm_trap_if; \ 820 bool trap_if = FLAG_wasm_trap_if; \
832 FLAG_wasm_trap_if = false; \ 821 FLAG_wasm_trap_if = false; \
833 RunWasm_##name(kExecuteCompiled); \ 822 RunWasm_##name(kExecuteCompiled); \
834 FLAG_wasm_trap_if = trap_if; \ 823 FLAG_wasm_trap_if = trap_if; \
835 } \ 824 } \
836 TEST(RunWasmInterpreted_##name) { RunWasm_##name(kExecuteInterpreted); } \ 825 TEST(RunWasmInterpreted_##name) { RunWasm_##name(kExecuteInterpreted); } \
837 void RunWasm_##name(WasmExecutionMode execution_mode) 826 void RunWasm_##name(WasmExecutionMode execution_mode)
838 827
839 #define WASM_EXEC_COMPILED_TEST(name) \ 828 #define WASM_EXEC_COMPILED_TEST(name) \
840 void RunWasm_##name(WasmExecutionMode execution_mode); \ 829 void RunWasm_##name(WasmExecutionMode execution_mode); \
841 TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \ 830 TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \
842 void RunWasm_##name(WasmExecutionMode execution_mode) 831 void RunWasm_##name(WasmExecutionMode execution_mode)
843 832
844 } // namespace 833 } // namespace
845 834
846 #endif 835 #endif
OLDNEW
« no previous file with comments | « test/cctest/wasm/test-run-wasm-64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698