| 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/wasm/wasm-interpreter.h" | 5 #include "src/wasm/wasm-interpreter.h" |
| 6 | 6 |
| 7 #include "src/utils.h" | 7 #include "src/utils.h" |
| 8 #include "src/wasm/decoder.h" | 8 #include "src/wasm/decoder.h" |
| 9 #include "src/wasm/function-body-decoder.h" | 9 #include "src/wasm/function-body-decoder.h" |
| 10 #include "src/wasm/wasm-external-refs.h" | 10 #include "src/wasm/wasm-external-refs.h" |
| (...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 921 &module_->function_tables[table_index]; | 921 &module_->function_tables[table_index]; |
| 922 if (entry_index >= table->values.size()) return nullptr; | 922 if (entry_index >= table->values.size()) return nullptr; |
| 923 uint32_t index = table->values[entry_index]; | 923 uint32_t index = table->values[entry_index]; |
| 924 if (index >= interpreter_code_.size()) return nullptr; | 924 if (index >= interpreter_code_.size()) return nullptr; |
| 925 return GetCode(index); | 925 return GetCode(index); |
| 926 } | 926 } |
| 927 | 927 |
| 928 InterpreterCode* Preprocess(InterpreterCode* code) { | 928 InterpreterCode* Preprocess(InterpreterCode* code) { |
| 929 if (code->targets == nullptr && code->start) { | 929 if (code->targets == nullptr && code->start) { |
| 930 // Compute the control targets map and the local declarations. | 930 // Compute the control targets map and the local declarations. |
| 931 CHECK(DecodeLocalDecls(code->locals, code->start, code->end)); | 931 CHECK(DecodeLocalDecls(&code->locals, code->start, code->end)); |
| 932 code->targets = new (zone_) ControlTransfers( | 932 code->targets = new (zone_) ControlTransfers( |
| 933 zone_, &code->locals, code->orig_start, code->orig_end); | 933 zone_, &code->locals, code->orig_start, code->orig_end); |
| 934 } | 934 } |
| 935 return code; | 935 return code; |
| 936 } | 936 } |
| 937 | 937 |
| 938 int AddFunction(const WasmFunction* function, const byte* code_start, | 938 int AddFunction(const WasmFunction* function, const byte* code_start, |
| 939 const byte* code_end) { | 939 const byte* code_end) { |
| 940 InterpreterCode code = { | 940 InterpreterCode code = { |
| 941 function, BodyLocalDecls(zone_), code_start, | 941 function, BodyLocalDecls(zone_), code_start, |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1063 // Entries on the stack of functions being evaluated. | 1063 // Entries on the stack of functions being evaluated. |
| 1064 struct Frame { | 1064 struct Frame { |
| 1065 InterpreterCode* code; | 1065 InterpreterCode* code; |
| 1066 pc_t call_pc; | 1066 pc_t call_pc; |
| 1067 pc_t ret_pc; | 1067 pc_t ret_pc; |
| 1068 sp_t sp; | 1068 sp_t sp; |
| 1069 | 1069 |
| 1070 // Limit of parameters. | 1070 // Limit of parameters. |
| 1071 sp_t plimit() { return sp + code->function->sig->parameter_count(); } | 1071 sp_t plimit() { return sp + code->function->sig->parameter_count(); } |
| 1072 // Limit of locals. | 1072 // Limit of locals. |
| 1073 sp_t llimit() { return plimit() + code->locals.total_local_count; } | 1073 sp_t llimit() { return plimit() + code->locals.type_list.size(); } |
| 1074 }; | 1074 }; |
| 1075 | 1075 |
| 1076 struct Block { | 1076 struct Block { |
| 1077 pc_t pc; | 1077 pc_t pc; |
| 1078 sp_t sp; | 1078 sp_t sp; |
| 1079 size_t fp; | 1079 size_t fp; |
| 1080 unsigned arity; | 1080 unsigned arity; |
| 1081 }; | 1081 }; |
| 1082 | 1082 |
| 1083 CodeMap* codemap_; | 1083 CodeMap* codemap_; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1112 frames_.push_back({code, 0, 0, stack_.size() - arity}); | 1112 frames_.push_back({code, 0, 0, stack_.size() - arity}); |
| 1113 blocks_.push_back( | 1113 blocks_.push_back( |
| 1114 {0, stack_.size(), frames_.size(), | 1114 {0, stack_.size(), frames_.size(), |
| 1115 static_cast<uint32_t>(code->function->sig->return_count())}); | 1115 static_cast<uint32_t>(code->function->sig->return_count())}); |
| 1116 frames_.back().ret_pc = InitLocals(code); | 1116 frames_.back().ret_pc = InitLocals(code); |
| 1117 TRACE(" => push func#%u @%zu\n", code->function->func_index, | 1117 TRACE(" => push func#%u @%zu\n", code->function->func_index, |
| 1118 frames_.back().ret_pc); | 1118 frames_.back().ret_pc); |
| 1119 } | 1119 } |
| 1120 | 1120 |
| 1121 pc_t InitLocals(InterpreterCode* code) { | 1121 pc_t InitLocals(InterpreterCode* code) { |
| 1122 for (auto p : code->locals.local_types) { | 1122 for (auto p : code->locals.type_list) { |
| 1123 WasmVal val; | 1123 WasmVal val; |
| 1124 switch (p.first) { | 1124 switch (p) { |
| 1125 case kWasmI32: | 1125 case kWasmI32: |
| 1126 val = WasmVal(static_cast<int32_t>(0)); | 1126 val = WasmVal(static_cast<int32_t>(0)); |
| 1127 break; | 1127 break; |
| 1128 case kWasmI64: | 1128 case kWasmI64: |
| 1129 val = WasmVal(static_cast<int64_t>(0)); | 1129 val = WasmVal(static_cast<int64_t>(0)); |
| 1130 break; | 1130 break; |
| 1131 case kWasmF32: | 1131 case kWasmF32: |
| 1132 val = WasmVal(static_cast<float>(0)); | 1132 val = WasmVal(static_cast<float>(0)); |
| 1133 break; | 1133 break; |
| 1134 case kWasmF64: | 1134 case kWasmF64: |
| 1135 val = WasmVal(static_cast<double>(0)); | 1135 val = WasmVal(static_cast<double>(0)); |
| 1136 break; | 1136 break; |
| 1137 default: | 1137 default: |
| 1138 UNREACHABLE(); | 1138 UNREACHABLE(); |
| 1139 break; | 1139 break; |
| 1140 } | 1140 } |
| 1141 stack_.insert(stack_.end(), p.second, val); | 1141 stack_.push_back(val); |
| 1142 } | 1142 } |
| 1143 return code->locals.decls_encoded_size; | 1143 return code->locals.encoded_size; |
| 1144 } | 1144 } |
| 1145 | 1145 |
| 1146 void CommitPc(pc_t pc) { | 1146 void CommitPc(pc_t pc) { |
| 1147 if (!frames_.empty()) { | 1147 if (!frames_.empty()) { |
| 1148 frames_.back().ret_pc = pc; | 1148 frames_.back().ret_pc = pc; |
| 1149 } | 1149 } |
| 1150 } | 1150 } |
| 1151 | 1151 |
| 1152 bool SkipBreakpoint(InterpreterCode* code, pc_t pc) { | 1152 bool SkipBreakpoint(InterpreterCode* code, pc_t pc) { |
| 1153 if (pc == break_pc_) { | 1153 if (pc == break_pc_) { |
| (...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1793 void WasmInterpreter::Run() { internals_->threads_[0]->Run(); } | 1793 void WasmInterpreter::Run() { internals_->threads_[0]->Run(); } |
| 1794 | 1794 |
| 1795 void WasmInterpreter::Pause() { internals_->threads_[0]->Pause(); } | 1795 void WasmInterpreter::Pause() { internals_->threads_[0]->Pause(); } |
| 1796 | 1796 |
| 1797 bool WasmInterpreter::SetBreakpoint(const WasmFunction* function, pc_t pc, | 1797 bool WasmInterpreter::SetBreakpoint(const WasmFunction* function, pc_t pc, |
| 1798 bool enabled) { | 1798 bool enabled) { |
| 1799 InterpreterCode* code = internals_->codemap_.FindCode(function); | 1799 InterpreterCode* code = internals_->codemap_.FindCode(function); |
| 1800 if (!code) return false; | 1800 if (!code) return false; |
| 1801 size_t size = static_cast<size_t>(code->end - code->start); | 1801 size_t size = static_cast<size_t>(code->end - code->start); |
| 1802 // Check bounds for {pc}. | 1802 // Check bounds for {pc}. |
| 1803 if (pc < code->locals.decls_encoded_size || pc >= size) return false; | 1803 if (pc < code->locals.encoded_size || pc >= size) return false; |
| 1804 // Make a copy of the code before enabling a breakpoint. | 1804 // Make a copy of the code before enabling a breakpoint. |
| 1805 if (enabled && code->orig_start == code->start) { | 1805 if (enabled && code->orig_start == code->start) { |
| 1806 code->start = reinterpret_cast<byte*>(zone_.New(size)); | 1806 code->start = reinterpret_cast<byte*>(zone_.New(size)); |
| 1807 memcpy(code->start, code->orig_start, size); | 1807 memcpy(code->start, code->orig_start, size); |
| 1808 code->end = code->start + size; | 1808 code->end = code->start + size; |
| 1809 } | 1809 } |
| 1810 bool prev = code->start[pc] == kInternalBreakpoint; | 1810 bool prev = code->start[pc] == kInternalBreakpoint; |
| 1811 if (enabled) { | 1811 if (enabled) { |
| 1812 code->start[pc] = kInternalBreakpoint; | 1812 code->start[pc] = kInternalBreakpoint; |
| 1813 } else { | 1813 } else { |
| 1814 code->start[pc] = code->orig_start[pc]; | 1814 code->start[pc] = code->orig_start[pc]; |
| 1815 } | 1815 } |
| 1816 return prev; | 1816 return prev; |
| 1817 } | 1817 } |
| 1818 | 1818 |
| 1819 bool WasmInterpreter::GetBreakpoint(const WasmFunction* function, pc_t pc) { | 1819 bool WasmInterpreter::GetBreakpoint(const WasmFunction* function, pc_t pc) { |
| 1820 InterpreterCode* code = internals_->codemap_.FindCode(function); | 1820 InterpreterCode* code = internals_->codemap_.FindCode(function); |
| 1821 if (!code) return false; | 1821 if (!code) return false; |
| 1822 size_t size = static_cast<size_t>(code->end - code->start); | 1822 size_t size = static_cast<size_t>(code->end - code->start); |
| 1823 // Check bounds for {pc}. | 1823 // Check bounds for {pc}. |
| 1824 if (pc < code->locals.decls_encoded_size || pc >= size) return false; | 1824 if (pc < code->locals.encoded_size || pc >= size) return false; |
| 1825 // Check if a breakpoint is present at that place in the code. | 1825 // Check if a breakpoint is present at that place in the code. |
| 1826 return code->start[pc] == kInternalBreakpoint; | 1826 return code->start[pc] == kInternalBreakpoint; |
| 1827 } | 1827 } |
| 1828 | 1828 |
| 1829 bool WasmInterpreter::SetTracing(const WasmFunction* function, bool enabled) { | 1829 bool WasmInterpreter::SetTracing(const WasmFunction* function, bool enabled) { |
| 1830 UNIMPLEMENTED(); | 1830 UNIMPLEMENTED(); |
| 1831 return false; | 1831 return false; |
| 1832 } | 1832 } |
| 1833 | 1833 |
| 1834 int WasmInterpreter::GetThreadCount() { | 1834 int WasmInterpreter::GetThreadCount() { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1888 | 1888 |
| 1889 ControlTransferMap WasmInterpreter::ComputeControlTransfersForTesting( | 1889 ControlTransferMap WasmInterpreter::ComputeControlTransfersForTesting( |
| 1890 Zone* zone, const byte* start, const byte* end) { | 1890 Zone* zone, const byte* start, const byte* end) { |
| 1891 ControlTransfers targets(zone, nullptr, start, end); | 1891 ControlTransfers targets(zone, nullptr, start, end); |
| 1892 return targets.map_; | 1892 return targets.map_; |
| 1893 } | 1893 } |
| 1894 | 1894 |
| 1895 } // namespace wasm | 1895 } // namespace wasm |
| 1896 } // namespace internal | 1896 } // namespace internal |
| 1897 } // namespace v8 | 1897 } // namespace v8 |
| OLD | NEW |