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 #include "src/wasm/ast-decoder.h" | 6 #include "src/wasm/ast-decoder.h" |
7 #include "src/wasm/decoder.h" | 7 #include "src/wasm/decoder.h" |
8 #include "src/wasm/wasm-external-refs.h" | 8 #include "src/wasm/wasm-external-refs.h" |
9 #include "src/wasm/wasm-module.h" | 9 #include "src/wasm/wasm-module.h" |
10 | 10 |
(...skipping 833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
844 auto result = map_.find(from); | 844 auto result = map_.find(from); |
845 if (result == map_.end()) { | 845 if (result == map_.end()) { |
846 V8_Fatal(__FILE__, __LINE__, "no control target for pc %zu", from); | 846 V8_Fatal(__FILE__, __LINE__, "no control target for pc %zu", from); |
847 } | 847 } |
848 return result->second; | 848 return result->second; |
849 } | 849 } |
850 }; | 850 }; |
851 | 851 |
852 // Code and metadata needed to execute a function. | 852 // Code and metadata needed to execute a function. |
853 struct InterpreterCode { | 853 struct InterpreterCode { |
854 const WasmFunction* function; // wasm function | 854 const WasmFunction* function; // wasm function |
855 AstLocalDecls locals; // local declarations | 855 AstLocalDecls locals; // local declarations |
856 const byte* orig_start; // start of original code | 856 const byte* orig_start; // start of original code |
857 const byte* orig_end; // end of original code | 857 const byte* orig_end; // end of original code |
858 byte* start; // start of (maybe altered) code | 858 byte* start; // start of (maybe altered) code |
859 byte* end; // end of (maybe altered) code | 859 byte* end; // end of (maybe altered) code |
860 ControlTransfers* targets; // helper for control flow. | 860 ControlTransfers* targets; // helper for control flow. |
| 861 BoolVector instruction_offsets; // valid instruction offsets |
861 | 862 |
862 const byte* at(pc_t pc) { return start + pc; } | 863 const byte* at(pc_t pc) { return start + pc; } |
863 }; | 864 }; |
864 | 865 |
| 866 namespace { |
| 867 |
| 868 pc_t FindPreviousInstruction(InterpreterCode* code, pc_t pc) { |
| 869 BoolVector& offsets = code->instruction_offsets; |
| 870 DCHECK(offsets[pc]); |
| 871 while (!offsets[--pc]) DCHECK_LE(0U, pc); |
| 872 return pc; |
| 873 } |
| 874 |
| 875 } // namespace |
| 876 |
865 // The main storage for interpreter code. It maps {WasmFunction} to the | 877 // The main storage for interpreter code. It maps {WasmFunction} to the |
866 // metadata needed to execute each function. | 878 // metadata needed to execute each function. |
867 class CodeMap { | 879 class CodeMap { |
868 public: | 880 public: |
869 Zone* zone_; | 881 Zone* zone_; |
870 const WasmModule* module_; | 882 const WasmModule* module_; |
871 ZoneVector<InterpreterCode> interpreter_code_; | 883 ZoneVector<InterpreterCode> interpreter_code_; |
872 | 884 |
873 CodeMap(const WasmModule* module, Zone* zone) | 885 CodeMap(const WasmModule* module, Zone* zone) |
874 : zone_(zone), module_(module), interpreter_code_(zone) { | 886 : zone_(zone), module_(module), interpreter_code_(zone) { |
(...skipping 28 matching lines...) Expand all Loading... |
903 return GetCode(index); | 915 return GetCode(index); |
904 } | 916 } |
905 | 917 |
906 InterpreterCode* Preprocess(InterpreterCode* code) { | 918 InterpreterCode* Preprocess(InterpreterCode* code) { |
907 if (code->targets == nullptr && code->start) { | 919 if (code->targets == nullptr && code->start) { |
908 // Compute the control targets map and the local declarations. | 920 // Compute the control targets map and the local declarations. |
909 CHECK(DecodeLocalDecls(code->locals, code->start, code->end)); | 921 CHECK(DecodeLocalDecls(code->locals, code->start, code->end)); |
910 code->targets = | 922 code->targets = |
911 new (zone_) ControlTransfers(zone_, code->locals.decls_encoded_size, | 923 new (zone_) ControlTransfers(zone_, code->locals.decls_encoded_size, |
912 code->orig_start, code->orig_end); | 924 code->orig_start, code->orig_end); |
| 925 |
| 926 // Initialize the instruction_offsets bitset. |
| 927 DCHECK(code->instruction_offsets.empty()); |
| 928 code->instruction_offsets.resize(code->end - code->start); |
| 929 const byte* pc = code->orig_start + code->locals.decls_encoded_size; |
| 930 while (pc < code->orig_end) { |
| 931 code->instruction_offsets[pc - code->orig_start] = 1; |
| 932 pc += OpcodeLength(pc, code->orig_end); |
| 933 } |
913 } | 934 } |
914 return code; | 935 return code; |
915 } | 936 } |
916 | 937 |
917 int AddFunction(const WasmFunction* function, const byte* code_start, | 938 int AddFunction(const WasmFunction* function, const byte* code_start, |
918 const byte* code_end) { | 939 const byte* code_end) { |
919 InterpreterCode code = { | 940 InterpreterCode code = {function, |
920 function, AstLocalDecls(zone_), code_start, | 941 AstLocalDecls(zone_), |
921 code_end, const_cast<byte*>(code_start), const_cast<byte*>(code_end), | 942 code_start, |
922 nullptr}; | 943 code_end, |
| 944 const_cast<byte*>(code_start), |
| 945 const_cast<byte*>(code_end), |
| 946 nullptr, |
| 947 BoolVector(zone_)}; |
923 | 948 |
924 DCHECK_EQ(interpreter_code_.size(), function->func_index); | 949 DCHECK_EQ(interpreter_code_.size(), function->func_index); |
925 interpreter_code_.push_back(code); | 950 interpreter_code_.push_back(code); |
926 return static_cast<int>(interpreter_code_.size()) - 1; | 951 return static_cast<int>(interpreter_code_.size()) - 1; |
927 } | 952 } |
928 | 953 |
929 bool SetFunctionCode(const WasmFunction* function, const byte* start, | 954 bool SetFunctionCode(const WasmFunction* function, const byte* start, |
930 const byte* end) { | 955 const byte* end) { |
931 InterpreterCode* code = FindCode(function); | 956 InterpreterCode* code = FindCode(function); |
932 if (code == nullptr) return false; | 957 if (code == nullptr) return false; |
(...skipping 23 matching lines...) Expand all Loading... |
956 | 981 |
957 //========================================================================== | 982 //========================================================================== |
958 // Implementation of public interface for WasmInterpreter::Thread. | 983 // Implementation of public interface for WasmInterpreter::Thread. |
959 //========================================================================== | 984 //========================================================================== |
960 | 985 |
961 virtual WasmInterpreter::State state() { return state_; } | 986 virtual WasmInterpreter::State state() { return state_; } |
962 | 987 |
963 virtual void PushFrame(const WasmFunction* function, WasmVal* args) { | 988 virtual void PushFrame(const WasmFunction* function, WasmVal* args) { |
964 InterpreterCode* code = codemap()->FindCode(function); | 989 InterpreterCode* code = codemap()->FindCode(function); |
965 CHECK_NOT_NULL(code); | 990 CHECK_NOT_NULL(code); |
| 991 codemap()->Preprocess(code); |
966 frames_.push_back({code, 0, 0, stack_.size()}); | 992 frames_.push_back({code, 0, 0, stack_.size()}); |
967 for (size_t i = 0; i < function->sig->parameter_count(); ++i) { | 993 for (size_t i = 0; i < function->sig->parameter_count(); ++i) { |
968 stack_.push_back(args[i]); | 994 stack_.push_back(args[i]); |
969 } | 995 } |
970 frames_.back().ret_pc = InitLocals(code); | 996 frames_.back().ret_pc = InitLocals(code); |
971 TRACE(" => PushFrame(#%u @%zu)\n", code->function->func_index, | 997 TRACE(" => PushFrame(#%u @%zu)\n", code->function->func_index, |
972 frames_.back().ret_pc); | 998 frames_.back().ret_pc); |
973 } | 999 } |
974 | 1000 |
975 virtual WasmInterpreter::State Run() { | 1001 virtual WasmInterpreter::State Run() { |
(...skipping 23 matching lines...) Expand all Loading... |
999 virtual void Reset() { | 1025 virtual void Reset() { |
1000 TRACE("----- RESET -----\n"); | 1026 TRACE("----- RESET -----\n"); |
1001 stack_.clear(); | 1027 stack_.clear(); |
1002 frames_.clear(); | 1028 frames_.clear(); |
1003 state_ = WasmInterpreter::STOPPED; | 1029 state_ = WasmInterpreter::STOPPED; |
1004 trap_reason_ = kTrapCount; | 1030 trap_reason_ = kTrapCount; |
1005 } | 1031 } |
1006 | 1032 |
1007 virtual int GetFrameCount() { return static_cast<int>(frames_.size()); } | 1033 virtual int GetFrameCount() { return static_cast<int>(frames_.size()); } |
1008 | 1034 |
1009 virtual const WasmFrame* GetFrame(int index) { | 1035 virtual const WasmInterpreterFrame* GetFrame(int index) { |
| 1036 Frame* frame = &frames_[index]; |
| 1037 DCHECK_LE(frame->sp, stack_.size()); |
| 1038 DCHECK_LE(stack_.size(), static_cast<size_t>(kMaxInt)); |
| 1039 // For all but the top frame, the pc is one behine the call instruction. |
| 1040 bool top_frame = static_cast<size_t>(index) == frames_.size() - 1; |
| 1041 pc_t pc = top_frame ? frame->ret_pc |
| 1042 : FindPreviousInstruction(frame->code, frame->ret_pc); |
| 1043 return new WasmInterpreterFrame(frame->code->function, // wasm function |
| 1044 static_cast<int>(pc), // pc |
| 1045 static_cast<int>(frame->sp), // fp |
| 1046 static_cast<int>(stack_.size())); // sp |
| 1047 } |
| 1048 |
| 1049 virtual WasmInterpreterFrame* GetMutableFrame(int index) { |
1010 UNIMPLEMENTED(); | 1050 UNIMPLEMENTED(); |
1011 return nullptr; | 1051 return nullptr; |
1012 } | 1052 } |
1013 | |
1014 virtual WasmFrame* GetMutableFrame(int index) { | |
1015 UNIMPLEMENTED(); | |
1016 return nullptr; | |
1017 } | |
1018 | 1053 |
1019 virtual WasmVal GetReturnValue() { | 1054 virtual WasmVal GetReturnValue() { |
1020 if (state_ == WasmInterpreter::TRAPPED) return WasmVal(0xdeadbeef); | 1055 if (state_ == WasmInterpreter::TRAPPED) return WasmVal(0xdeadbeef); |
1021 CHECK_EQ(WasmInterpreter::FINISHED, state_); | 1056 CHECK_EQ(WasmInterpreter::FINISHED, state_); |
1022 CHECK_EQ(1, stack_.size()); | 1057 CHECK_EQ(1, stack_.size()); |
1023 return stack_[0]; | 1058 return stack_[0]; |
1024 } | 1059 } |
1025 | 1060 |
1026 virtual pc_t GetBreakpointPc() { return break_pc_; } | 1061 virtual pc_t GetBreakpointPc() { return break_pc_; } |
1027 | 1062 |
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1645 | 1680 |
1646 void TraceStack(const char* phase, pc_t pc) { | 1681 void TraceStack(const char* phase, pc_t pc) { |
1647 if (FLAG_trace_wasm_interpreter) { | 1682 if (FLAG_trace_wasm_interpreter) { |
1648 PrintF("%s @%zu", phase, pc); | 1683 PrintF("%s @%zu", phase, pc); |
1649 UNIMPLEMENTED(); | 1684 UNIMPLEMENTED(); |
1650 PrintF("\n"); | 1685 PrintF("\n"); |
1651 } | 1686 } |
1652 } | 1687 } |
1653 | 1688 |
1654 void TraceValueStack() { | 1689 void TraceValueStack() { |
| 1690 #if DEBUG |
1655 Frame* top = frames_.size() > 0 ? &frames_.back() : nullptr; | 1691 Frame* top = frames_.size() > 0 ? &frames_.back() : nullptr; |
1656 sp_t sp = top ? top->sp : 0; | 1692 sp_t sp = top ? top->sp : 0; |
1657 sp_t plimit = top ? top->plimit() : 0; | 1693 sp_t plimit = top ? top->plimit() : 0; |
1658 sp_t llimit = top ? top->llimit() : 0; | 1694 sp_t llimit = top ? top->llimit() : 0; |
1659 if (FLAG_trace_wasm_interpreter) { | 1695 if (FLAG_trace_wasm_interpreter) { |
1660 for (size_t i = sp; i < stack_.size(); ++i) { | 1696 for (size_t i = sp; i < stack_.size(); ++i) { |
1661 if (i < plimit) | 1697 if (i < plimit) |
1662 PrintF(" p%zu:", i); | 1698 PrintF(" p%zu:", i); |
1663 else if (i < llimit) | 1699 else if (i < llimit) |
1664 PrintF(" l%zu:", i); | 1700 PrintF(" l%zu:", i); |
(...skipping 15 matching lines...) Expand all Loading... |
1680 break; | 1716 break; |
1681 case kAstStmt: | 1717 case kAstStmt: |
1682 PrintF("void"); | 1718 PrintF("void"); |
1683 break; | 1719 break; |
1684 default: | 1720 default: |
1685 UNREACHABLE(); | 1721 UNREACHABLE(); |
1686 break; | 1722 break; |
1687 } | 1723 } |
1688 } | 1724 } |
1689 } | 1725 } |
| 1726 #endif |
1690 } | 1727 } |
1691 }; | 1728 }; |
1692 | 1729 |
1693 //============================================================================ | 1730 //============================================================================ |
1694 // The implementation details of the interpreter. | 1731 // The implementation details of the interpreter. |
1695 //============================================================================ | 1732 //============================================================================ |
1696 class WasmInterpreterInternals : public ZoneObject { | 1733 class WasmInterpreterInternals : public ZoneObject { |
1697 public: | 1734 public: |
1698 WasmModuleInstance* instance_; | 1735 WasmModuleInstance* instance_; |
1699 CodeMap codemap_; | 1736 CodeMap codemap_; |
1700 ZoneVector<ThreadImpl*> threads_; | 1737 ZoneVector<ThreadImpl*> threads_; |
1701 | 1738 |
1702 WasmInterpreterInternals(Zone* zone, WasmModuleInstance* instance) | 1739 WasmInterpreterInternals(Zone* zone, WasmModuleInstance* instance) |
1703 : instance_(instance), | 1740 : instance_(instance), |
1704 codemap_(instance_ ? instance_->module : nullptr, zone), | 1741 codemap_(instance_ ? instance_->module : nullptr, zone), |
1705 threads_(zone) { | 1742 threads_(zone) { |
1706 threads_.push_back(new ThreadImpl(zone, &codemap_, instance)); | 1743 threads_.push_back(new ThreadImpl(zone, &codemap_, instance)); |
1707 } | 1744 } |
1708 | 1745 |
1709 void Delete() { | 1746 void Delete() { |
1710 // TODO(titzer): CFI doesn't like threads in the ZoneVector. | 1747 // TODO(titzer): CFI doesn't like threads in the ZoneVector. |
1711 for (auto t : threads_) delete t; | 1748 for (auto t : threads_) delete t; |
1712 threads_.resize(0); | 1749 threads_.resize(0); |
1713 } | 1750 } |
1714 }; | 1751 }; |
1715 | 1752 |
1716 //============================================================================ | 1753 //============================================================================ |
1717 // Implementation of the public interface of the interpreter. | 1754 // Implementation of the public interface of the interpreter. |
1718 //============================================================================ | 1755 //============================================================================ |
1719 WasmInterpreter::WasmInterpreter(WasmModuleInstance* instance, | 1756 WasmInterpreter::WasmInterpreter(WasmModuleInstance* instance, Zone* zone) |
1720 base::AccountingAllocator* allocator) | 1757 : zone_(zone), |
1721 : zone_(allocator), | 1758 internals_(new (zone_) WasmInterpreterInternals(zone_, instance)) {} |
1722 internals_(new (&zone_) WasmInterpreterInternals(&zone_, instance)) {} | |
1723 | 1759 |
1724 WasmInterpreter::~WasmInterpreter() { internals_->Delete(); } | 1760 WasmInterpreter::~WasmInterpreter() { internals_->Delete(); } |
1725 | 1761 |
1726 void WasmInterpreter::Run() { internals_->threads_[0]->Run(); } | 1762 void WasmInterpreter::Run() { internals_->threads_[0]->Run(); } |
1727 | 1763 |
1728 void WasmInterpreter::Pause() { internals_->threads_[0]->Pause(); } | 1764 void WasmInterpreter::Pause() { internals_->threads_[0]->Pause(); } |
1729 | 1765 |
1730 bool WasmInterpreter::SetBreakpoint(const WasmFunction* function, pc_t pc, | 1766 bool WasmInterpreter::SetBreakpoint(uint32_t function_index, pc_t pc, |
1731 bool enabled) { | 1767 bool enabled) { |
1732 InterpreterCode* code = internals_->codemap_.FindCode(function); | 1768 auto interpreter_code = internals_->codemap_.interpreter_code_; |
1733 if (!code) return false; | 1769 if (function_index > interpreter_code.size()) return false; |
| 1770 InterpreterCode* code = internals_->codemap_.GetCode(function_index); |
1734 size_t size = static_cast<size_t>(code->end - code->start); | 1771 size_t size = static_cast<size_t>(code->end - code->start); |
1735 // Check bounds for {pc}. | 1772 // Check bounds for {pc}. |
1736 if (pc < code->locals.decls_encoded_size || pc >= size) return false; | 1773 if (pc >= size) return false; |
| 1774 // Check that it's a valid instruction offset. |
| 1775 DCHECK_LE(pc, code->instruction_offsets.size()); |
| 1776 if (!code->instruction_offsets[pc]) return false; |
1737 // Make a copy of the code before enabling a breakpoint. | 1777 // Make a copy of the code before enabling a breakpoint. |
1738 if (enabled && code->orig_start == code->start) { | 1778 if (enabled && code->orig_start == code->start) { |
1739 code->start = reinterpret_cast<byte*>(zone_.New(size)); | 1779 code->start = reinterpret_cast<byte*>(zone_->New(size)); |
1740 memcpy(code->start, code->orig_start, size); | 1780 memcpy(code->start, code->orig_start, size); |
1741 code->end = code->start + size; | 1781 code->end = code->start + size; |
1742 } | 1782 } |
1743 bool prev = code->start[pc] == kInternalBreakpoint; | 1783 bool prev = code->start[pc] == kInternalBreakpoint; |
1744 if (enabled) { | 1784 code->start[pc] = enabled ? kInternalBreakpoint : code->orig_start[pc]; |
1745 code->start[pc] = kInternalBreakpoint; | |
1746 } else { | |
1747 code->start[pc] = code->orig_start[pc]; | |
1748 } | |
1749 return prev; | 1785 return prev; |
1750 } | 1786 } |
1751 | 1787 |
1752 bool WasmInterpreter::GetBreakpoint(const WasmFunction* function, pc_t pc) { | 1788 bool WasmInterpreter::GetBreakpoint(uint32_t function_index, pc_t pc) { |
1753 InterpreterCode* code = internals_->codemap_.FindCode(function); | 1789 auto interpreter_code = internals_->codemap_.interpreter_code_; |
1754 if (!code) return false; | 1790 if (function_index > interpreter_code.size()) return false; |
| 1791 InterpreterCode* code = internals_->codemap_.GetCode(function_index); |
1755 size_t size = static_cast<size_t>(code->end - code->start); | 1792 size_t size = static_cast<size_t>(code->end - code->start); |
1756 // Check bounds for {pc}. | 1793 // Check bounds for {pc}. |
1757 if (pc < code->locals.decls_encoded_size || pc >= size) return false; | 1794 if (pc >= size) return false; |
| 1795 // Check that it's a valid instruction offset. |
| 1796 DCHECK_LE(pc, code->instruction_offsets.size()); |
| 1797 if (!code->instruction_offsets[pc]) return false; |
1758 // Check if a breakpoint is present at that place in the code. | 1798 // Check if a breakpoint is present at that place in the code. |
1759 return code->start[pc] == kInternalBreakpoint; | 1799 return code->start[pc] == kInternalBreakpoint; |
1760 } | 1800 } |
1761 | 1801 |
1762 bool WasmInterpreter::SetTracing(const WasmFunction* function, bool enabled) { | 1802 bool WasmInterpreter::SetTracing(const WasmFunction* function, bool enabled) { |
1763 UNIMPLEMENTED(); | 1803 UNIMPLEMENTED(); |
1764 return false; | 1804 return false; |
1765 } | 1805 } |
1766 | 1806 |
1767 int WasmInterpreter::GetThreadCount() { | 1807 int WasmInterpreter::GetThreadCount() { |
1768 return 1; // only one thread for now. | 1808 return 1; // only one thread for now. |
1769 } | 1809 } |
1770 | 1810 |
1771 WasmInterpreter::Thread* WasmInterpreter::GetThread(int id) { | 1811 WasmInterpreter::Thread* WasmInterpreter::GetThread(int id) { |
1772 CHECK_EQ(0, id); // only one thread for now. | 1812 CHECK_EQ(0, id); // only one thread for now. |
1773 return internals_->threads_[id]; | 1813 return internals_->threads_[id]; |
1774 } | 1814 } |
1775 | 1815 |
1776 WasmVal WasmInterpreter::GetLocalVal(const WasmFrame* frame, int index) { | 1816 WasmVal WasmInterpreter::GetLocalVal(const WasmInterpreterFrame* frame, |
| 1817 int index) { |
1777 CHECK_GE(index, 0); | 1818 CHECK_GE(index, 0); |
1778 UNIMPLEMENTED(); | 1819 UNIMPLEMENTED(); |
| 1820 USE(frame->fp_); |
| 1821 USE(frame->sp_); |
| 1822 WasmVal none; |
| 1823 none.type = kAstStmt; |
| 1824 return none; |
| 1825 } |
| 1826 |
| 1827 WasmVal WasmInterpreter::GetExprVal(const WasmInterpreterFrame* frame, int pc) { |
| 1828 UNIMPLEMENTED(); |
1779 WasmVal none; | 1829 WasmVal none; |
1780 none.type = kAstStmt; | 1830 none.type = kAstStmt; |
1781 return none; | 1831 return none; |
1782 } | 1832 } |
1783 | 1833 |
1784 WasmVal WasmInterpreter::GetExprVal(const WasmFrame* frame, int pc) { | 1834 void WasmInterpreter::SetLocalVal(WasmInterpreterFrame* frame, int index, |
1785 UNIMPLEMENTED(); | 1835 WasmVal val) { |
1786 WasmVal none; | |
1787 none.type = kAstStmt; | |
1788 return none; | |
1789 } | |
1790 | |
1791 void WasmInterpreter::SetLocalVal(WasmFrame* frame, int index, WasmVal val) { | |
1792 UNIMPLEMENTED(); | 1836 UNIMPLEMENTED(); |
1793 } | 1837 } |
1794 | 1838 |
1795 void WasmInterpreter::SetExprVal(WasmFrame* frame, int pc, WasmVal val) { | 1839 void WasmInterpreter::SetExprVal(WasmInterpreterFrame* frame, int pc, |
| 1840 WasmVal val) { |
1796 UNIMPLEMENTED(); | 1841 UNIMPLEMENTED(); |
1797 } | 1842 } |
1798 | 1843 |
1799 size_t WasmInterpreter::GetMemorySize() { | 1844 size_t WasmInterpreter::GetMemorySize() { |
1800 return internals_->instance_->mem_size; | 1845 return internals_->instance_->mem_size; |
1801 } | 1846 } |
1802 | 1847 |
1803 WasmVal WasmInterpreter::ReadMemory(size_t offset) { | 1848 WasmVal WasmInterpreter::ReadMemory(size_t offset) { |
1804 UNIMPLEMENTED(); | 1849 UNIMPLEMENTED(); |
1805 return WasmVal(); | 1850 return WasmVal(); |
(...skipping 15 matching lines...) Expand all Loading... |
1821 | 1866 |
1822 ControlTransferMap WasmInterpreter::ComputeControlTransfersForTesting( | 1867 ControlTransferMap WasmInterpreter::ComputeControlTransfersForTesting( |
1823 Zone* zone, const byte* start, const byte* end) { | 1868 Zone* zone, const byte* start, const byte* end) { |
1824 ControlTransfers targets(zone, 0, start, end); | 1869 ControlTransfers targets(zone, 0, start, end); |
1825 return targets.map_; | 1870 return targets.map_; |
1826 } | 1871 } |
1827 | 1872 |
1828 } // namespace wasm | 1873 } // namespace wasm |
1829 } // namespace internal | 1874 } // namespace internal |
1830 } // namespace v8 | 1875 } // namespace v8 |
OLD | NEW |