| 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 <type_traits> | 5 #include <type_traits> |
| 6 | 6 |
| 7 #include "src/wasm/wasm-interpreter.h" | 7 #include "src/wasm/wasm-interpreter.h" |
| 8 | 8 |
| 9 #include "src/conversions.h" | 9 #include "src/conversions.h" |
| 10 #include "src/objects-inl.h" | 10 #include "src/objects-inl.h" |
| (...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 928 | 928 |
| 929 //========================================================================== | 929 //========================================================================== |
| 930 // Implementation of public interface for WasmInterpreter::Thread. | 930 // Implementation of public interface for WasmInterpreter::Thread. |
| 931 //========================================================================== | 931 //========================================================================== |
| 932 | 932 |
| 933 WasmInterpreter::State state() { return state_; } | 933 WasmInterpreter::State state() { return state_; } |
| 934 | 934 |
| 935 void PushFrame(const WasmFunction* function, WasmVal* args) { | 935 void PushFrame(const WasmFunction* function, WasmVal* args) { |
| 936 InterpreterCode* code = codemap()->FindCode(function); | 936 InterpreterCode* code = codemap()->FindCode(function); |
| 937 CHECK_NOT_NULL(code); | 937 CHECK_NOT_NULL(code); |
| 938 ++num_interpreted_calls_; |
| 938 frames_.push_back({code, 0, 0, stack_.size()}); | 939 frames_.push_back({code, 0, 0, stack_.size()}); |
| 939 for (size_t i = 0; i < function->sig->parameter_count(); ++i) { | 940 for (size_t i = 0; i < function->sig->parameter_count(); ++i) { |
| 940 stack_.push_back(args[i]); | 941 stack_.push_back(args[i]); |
| 941 } | 942 } |
| 942 frames_.back().ret_pc = InitLocals(code); | 943 frames_.back().ret_pc = InitLocals(code); |
| 943 blocks_.push_back( | 944 blocks_.push_back( |
| 944 {0, stack_.size(), frames_.size(), | 945 {0, stack_.size(), frames_.size(), |
| 945 static_cast<uint32_t>(code->function->sig->return_count())}); | 946 static_cast<uint32_t>(code->function->sig->return_count())}); |
| 946 TRACE(" => PushFrame(#%u @%zu)\n", code->function->func_index, | 947 TRACE(" => PushFrame(#%u @%zu)\n", code->function->func_index, |
| 947 frames_.back().ret_pc); | 948 frames_.back().ret_pc); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1002 if (state_ == WasmInterpreter::TRAPPED) return WasmVal(0xdeadbeef); | 1003 if (state_ == WasmInterpreter::TRAPPED) return WasmVal(0xdeadbeef); |
| 1003 CHECK_EQ(WasmInterpreter::FINISHED, state_); | 1004 CHECK_EQ(WasmInterpreter::FINISHED, state_); |
| 1004 CHECK_LT(static_cast<size_t>(index), stack_.size()); | 1005 CHECK_LT(static_cast<size_t>(index), stack_.size()); |
| 1005 return stack_[index]; | 1006 return stack_[index]; |
| 1006 } | 1007 } |
| 1007 | 1008 |
| 1008 pc_t GetBreakpointPc() { return break_pc_; } | 1009 pc_t GetBreakpointPc() { return break_pc_; } |
| 1009 | 1010 |
| 1010 bool PossibleNondeterminism() { return possible_nondeterminism_; } | 1011 bool PossibleNondeterminism() { return possible_nondeterminism_; } |
| 1011 | 1012 |
| 1013 uint64_t NumInterpretedCalls() { return num_interpreted_calls_; } |
| 1014 |
| 1012 void AddBreakFlags(uint8_t flags) { break_flags_ |= flags; } | 1015 void AddBreakFlags(uint8_t flags) { break_flags_ |= flags; } |
| 1013 | 1016 |
| 1014 void ClearBreakFlags() { break_flags_ = WasmInterpreter::BreakFlag::None; } | 1017 void ClearBreakFlags() { break_flags_ = WasmInterpreter::BreakFlag::None; } |
| 1015 | 1018 |
| 1016 private: | 1019 private: |
| 1017 // Entries on the stack of functions being evaluated. | 1020 // Entries on the stack of functions being evaluated. |
| 1018 struct Frame { | 1021 struct Frame { |
| 1019 InterpreterCode* code; | 1022 InterpreterCode* code; |
| 1020 pc_t call_pc; | 1023 pc_t call_pc; |
| 1021 pc_t ret_pc; | 1024 pc_t ret_pc; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1037 CodeMap* codemap_; | 1040 CodeMap* codemap_; |
| 1038 WasmInstance* instance_; | 1041 WasmInstance* instance_; |
| 1039 ZoneVector<WasmVal> stack_; | 1042 ZoneVector<WasmVal> stack_; |
| 1040 ZoneVector<Frame> frames_; | 1043 ZoneVector<Frame> frames_; |
| 1041 ZoneVector<Block> blocks_; | 1044 ZoneVector<Block> blocks_; |
| 1042 WasmInterpreter::State state_ = WasmInterpreter::STOPPED; | 1045 WasmInterpreter::State state_ = WasmInterpreter::STOPPED; |
| 1043 pc_t break_pc_ = kInvalidPc; | 1046 pc_t break_pc_ = kInvalidPc; |
| 1044 TrapReason trap_reason_ = kTrapCount; | 1047 TrapReason trap_reason_ = kTrapCount; |
| 1045 bool possible_nondeterminism_ = false; | 1048 bool possible_nondeterminism_ = false; |
| 1046 uint8_t break_flags_ = 0; // a combination of WasmInterpreter::BreakFlag | 1049 uint8_t break_flags_ = 0; // a combination of WasmInterpreter::BreakFlag |
| 1050 uint64_t num_interpreted_calls_ = 0; |
| 1047 | 1051 |
| 1048 CodeMap* codemap() { return codemap_; } | 1052 CodeMap* codemap() { return codemap_; } |
| 1049 WasmInstance* instance() { return instance_; } | 1053 WasmInstance* instance() { return instance_; } |
| 1050 const WasmModule* module() { return instance_->module; } | 1054 const WasmModule* module() { return instance_->module; } |
| 1051 | 1055 |
| 1052 void DoTrap(TrapReason trap, pc_t pc) { | 1056 void DoTrap(TrapReason trap, pc_t pc) { |
| 1053 state_ = WasmInterpreter::TRAPPED; | 1057 state_ = WasmInterpreter::TRAPPED; |
| 1054 trap_reason_ = trap; | 1058 trap_reason_ = trap; |
| 1055 CommitPc(pc); | 1059 CommitPc(pc); |
| 1056 } | 1060 } |
| 1057 | 1061 |
| 1058 // Push a frame with arguments already on the stack. | 1062 // Push a frame with arguments already on the stack. |
| 1059 void PushFrame(InterpreterCode* code, pc_t call_pc, pc_t ret_pc) { | 1063 void PushFrame(InterpreterCode* code, pc_t call_pc, pc_t ret_pc) { |
| 1060 CHECK_NOT_NULL(code); | 1064 CHECK_NOT_NULL(code); |
| 1061 DCHECK(!frames_.empty()); | 1065 DCHECK(!frames_.empty()); |
| 1066 ++num_interpreted_calls_; |
| 1062 frames_.back().call_pc = call_pc; | 1067 frames_.back().call_pc = call_pc; |
| 1063 frames_.back().ret_pc = ret_pc; | 1068 frames_.back().ret_pc = ret_pc; |
| 1064 size_t arity = code->function->sig->parameter_count(); | 1069 size_t arity = code->function->sig->parameter_count(); |
| 1065 DCHECK_GE(stack_.size(), arity); | 1070 DCHECK_GE(stack_.size(), arity); |
| 1066 // The parameters will overlap the arguments already on the stack. | 1071 // The parameters will overlap the arguments already on the stack. |
| 1067 frames_.push_back({code, 0, 0, stack_.size() - arity}); | 1072 frames_.push_back({code, 0, 0, stack_.size() - arity}); |
| 1068 blocks_.push_back( | 1073 blocks_.push_back( |
| 1069 {0, stack_.size(), frames_.size(), | 1074 {0, stack_.size(), frames_.size(), |
| 1070 static_cast<uint32_t>(code->function->sig->return_count())}); | 1075 static_cast<uint32_t>(code->function->sig->return_count())}); |
| 1071 frames_.back().ret_pc = InitLocals(code); | 1076 frames_.back().ret_pc = InitLocals(code); |
| (...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1790 return InterpretedFrame(function, pc, fp, sp); | 1795 return InterpretedFrame(function, pc, fp, sp); |
| 1791 }; | 1796 }; |
| 1792 return ToImpl(this)->GetMutableFrame(index, frame_cons); | 1797 return ToImpl(this)->GetMutableFrame(index, frame_cons); |
| 1793 } | 1798 } |
| 1794 WasmVal WasmInterpreter::Thread::GetReturnValue(int index) { | 1799 WasmVal WasmInterpreter::Thread::GetReturnValue(int index) { |
| 1795 return ToImpl(this)->GetReturnValue(index); | 1800 return ToImpl(this)->GetReturnValue(index); |
| 1796 } | 1801 } |
| 1797 bool WasmInterpreter::Thread::PossibleNondeterminism() { | 1802 bool WasmInterpreter::Thread::PossibleNondeterminism() { |
| 1798 return ToImpl(this)->PossibleNondeterminism(); | 1803 return ToImpl(this)->PossibleNondeterminism(); |
| 1799 } | 1804 } |
| 1805 uint64_t WasmInterpreter::Thread::NumInterpretedCalls() { |
| 1806 return ToImpl(this)->NumInterpretedCalls(); |
| 1807 } |
| 1800 void WasmInterpreter::Thread::AddBreakFlags(uint8_t flags) { | 1808 void WasmInterpreter::Thread::AddBreakFlags(uint8_t flags) { |
| 1801 ToImpl(this)->AddBreakFlags(flags); | 1809 ToImpl(this)->AddBreakFlags(flags); |
| 1802 } | 1810 } |
| 1803 void WasmInterpreter::Thread::ClearBreakFlags() { | 1811 void WasmInterpreter::Thread::ClearBreakFlags() { |
| 1804 ToImpl(this)->ClearBreakFlags(); | 1812 ToImpl(this)->ClearBreakFlags(); |
| 1805 } | 1813 } |
| 1806 | 1814 |
| 1807 //============================================================================ | 1815 //============================================================================ |
| 1808 // The implementation details of the interpreter. | 1816 // The implementation details of the interpreter. |
| 1809 //============================================================================ | 1817 //============================================================================ |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1943 return none; | 1951 return none; |
| 1944 } | 1952 } |
| 1945 | 1953 |
| 1946 void InterpretedFrame::SetLocalVal(int index, WasmVal val) { UNIMPLEMENTED(); } | 1954 void InterpretedFrame::SetLocalVal(int index, WasmVal val) { UNIMPLEMENTED(); } |
| 1947 | 1955 |
| 1948 void InterpretedFrame::SetExprVal(int pc, WasmVal val) { UNIMPLEMENTED(); } | 1956 void InterpretedFrame::SetExprVal(int pc, WasmVal val) { UNIMPLEMENTED(); } |
| 1949 | 1957 |
| 1950 } // namespace wasm | 1958 } // namespace wasm |
| 1951 } // namespace internal | 1959 } // namespace internal |
| 1952 } // namespace v8 | 1960 } // namespace v8 |
| OLD | NEW |