| 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 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 911 code->targets = nullptr; | 911 code->targets = nullptr; |
| 912 code->orig_start = start; | 912 code->orig_start = start; |
| 913 code->orig_end = end; | 913 code->orig_end = end; |
| 914 code->start = const_cast<byte*>(start); | 914 code->start = const_cast<byte*>(start); |
| 915 code->end = const_cast<byte*>(end); | 915 code->end = const_cast<byte*>(end); |
| 916 Preprocess(code); | 916 Preprocess(code); |
| 917 return true; | 917 return true; |
| 918 } | 918 } |
| 919 }; | 919 }; |
| 920 | 920 |
| 921 namespace { |
| 921 // Responsible for executing code directly. | 922 // Responsible for executing code directly. |
| 922 class WasmInterpreter::ThreadImpl : public ZoneObject { | 923 class ThreadImpl { |
| 923 public: | 924 public: |
| 924 ThreadImpl(Zone* zone, CodeMap* codemap, WasmInstance* instance) | 925 ThreadImpl(Zone* zone, CodeMap* codemap, WasmInstance* instance) |
| 925 : codemap_(codemap), | 926 : codemap_(codemap), |
| 926 instance_(instance), | 927 instance_(instance), |
| 927 stack_(zone), | 928 stack_(zone), |
| 928 frames_(zone), | 929 frames_(zone), |
| 929 blocks_(zone), | 930 blocks_(zone), |
| 930 state_(WasmInterpreter::STOPPED), | 931 state_(WasmInterpreter::STOPPED), |
| 931 break_pc_(kInvalidPc), | 932 break_pc_(kInvalidPc), |
| 932 trap_reason_(kTrapCount), | 933 trap_reason_(kTrapCount), |
| 933 possible_nondeterminism_(false) {} | 934 possible_nondeterminism_(false) {} |
| 934 | 935 |
| 935 ~ThreadImpl() {} | |
| 936 | |
| 937 //========================================================================== | 936 //========================================================================== |
| 938 // Implementation of public interface for WasmInterpreter::Thread. | 937 // Implementation of public interface for WasmInterpreter::Thread. |
| 939 //========================================================================== | 938 //========================================================================== |
| 940 | 939 |
| 941 WasmInterpreter::State state() { return state_; } | 940 WasmInterpreter::State state() { return state_; } |
| 942 | 941 |
| 943 void PushFrame(const WasmFunction* function, WasmVal* args) { | 942 void PushFrame(const WasmFunction* function, WasmVal* args) { |
| 944 InterpreterCode* code = codemap()->FindCode(function); | 943 InterpreterCode* code = codemap()->FindCode(function); |
| 945 CHECK_NOT_NULL(code); | 944 CHECK_NOT_NULL(code); |
| 946 frames_.push_back({code, 0, 0, stack_.size()}); | 945 frames_.push_back({code, 0, 0, stack_.size()}); |
| (...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1691 break; | 1690 break; |
| 1692 default: | 1691 default: |
| 1693 UNREACHABLE(); | 1692 UNREACHABLE(); |
| 1694 break; | 1693 break; |
| 1695 } | 1694 } |
| 1696 } | 1695 } |
| 1697 } | 1696 } |
| 1698 } | 1697 } |
| 1699 }; | 1698 }; |
| 1700 | 1699 |
| 1700 // Converters between WasmInterpreter::Thread and WasmInterpreter::ThreadImpl. |
| 1701 // Thread* is the public interface, without knowledge of the object layout. |
| 1702 // This cast is potentially risky, but as long as we always cast it back before |
| 1703 // accessing any data, it should be fine. UBSan is not complaining. |
| 1704 WasmInterpreter::Thread* ToThread(ThreadImpl* impl) { |
| 1705 return reinterpret_cast<WasmInterpreter::Thread*>(impl); |
| 1706 } |
| 1707 static ThreadImpl* ToImpl(WasmInterpreter::Thread* thread) { |
| 1708 return reinterpret_cast<ThreadImpl*>(thread); |
| 1709 } |
| 1710 } // namespace |
| 1711 |
| 1701 //============================================================================ | 1712 //============================================================================ |
| 1702 // Forwarding functions of WasmInterpreter::Thread (pimpl idiom). | 1713 // Implementation of the pimpl idiom for WasmInterpreter::Thread. |
| 1714 // Instead of placing a pointer to the ThreadImpl inside of the Thread object, |
| 1715 // we just reinterpret_cast them. ThreadImpls are only allocated inside this |
| 1716 // translation unit anyway. |
| 1703 //============================================================================ | 1717 //============================================================================ |
| 1704 WasmInterpreter::Thread::Thread(ThreadImpl* impl) : impl_(impl) {} | |
| 1705 WasmInterpreter::State WasmInterpreter::Thread::state() { | 1718 WasmInterpreter::State WasmInterpreter::Thread::state() { |
| 1706 return impl_->state(); | 1719 return ToImpl(this)->state(); |
| 1707 } | 1720 } |
| 1708 void WasmInterpreter::Thread::PushFrame(const WasmFunction* function, | 1721 void WasmInterpreter::Thread::PushFrame(const WasmFunction* function, |
| 1709 WasmVal* args) { | 1722 WasmVal* args) { |
| 1710 return impl_->PushFrame(function, args); | 1723 return ToImpl(this)->PushFrame(function, args); |
| 1711 } | 1724 } |
| 1712 WasmInterpreter::State WasmInterpreter::Thread::Run() { return impl_->Run(); } | 1725 WasmInterpreter::State WasmInterpreter::Thread::Run() { |
| 1713 WasmInterpreter::State WasmInterpreter::Thread::Step() { return impl_->Step(); } | 1726 return ToImpl(this)->Run(); |
| 1714 void WasmInterpreter::Thread::Pause() { return impl_->Pause(); } | 1727 } |
| 1715 void WasmInterpreter::Thread::Reset() { return impl_->Reset(); } | 1728 WasmInterpreter::State WasmInterpreter::Thread::Step() { |
| 1729 return ToImpl(this)->Step(); |
| 1730 } |
| 1731 void WasmInterpreter::Thread::Pause() { return ToImpl(this)->Pause(); } |
| 1732 void WasmInterpreter::Thread::Reset() { return ToImpl(this)->Reset(); } |
| 1716 pc_t WasmInterpreter::Thread::GetBreakpointPc() { | 1733 pc_t WasmInterpreter::Thread::GetBreakpointPc() { |
| 1717 return impl_->GetBreakpointPc(); | 1734 return ToImpl(this)->GetBreakpointPc(); |
| 1718 } | 1735 } |
| 1719 int WasmInterpreter::Thread::GetFrameCount() { return impl_->GetFrameCount(); } | 1736 int WasmInterpreter::Thread::GetFrameCount() { |
| 1737 return ToImpl(this)->GetFrameCount(); |
| 1738 } |
| 1720 const WasmFrame* WasmInterpreter::Thread::GetFrame(int index) { | 1739 const WasmFrame* WasmInterpreter::Thread::GetFrame(int index) { |
| 1721 return impl_->GetFrame(index); | 1740 return ToImpl(this)->GetFrame(index); |
| 1722 } | 1741 } |
| 1723 WasmFrame* WasmInterpreter::Thread::GetMutableFrame(int index) { | 1742 WasmFrame* WasmInterpreter::Thread::GetMutableFrame(int index) { |
| 1724 return impl_->GetMutableFrame(index); | 1743 return ToImpl(this)->GetMutableFrame(index); |
| 1725 } | 1744 } |
| 1726 WasmVal WasmInterpreter::Thread::GetReturnValue(int index) { | 1745 WasmVal WasmInterpreter::Thread::GetReturnValue(int index) { |
| 1727 return impl_->GetReturnValue(index); | 1746 return ToImpl(this)->GetReturnValue(index); |
| 1728 } | 1747 } |
| 1729 bool WasmInterpreter::Thread::PossibleNondeterminism() { | 1748 bool WasmInterpreter::Thread::PossibleNondeterminism() { |
| 1730 return impl_->PossibleNondeterminism(); | 1749 return ToImpl(this)->PossibleNondeterminism(); |
| 1731 } | 1750 } |
| 1732 | 1751 |
| 1733 //============================================================================ | 1752 //============================================================================ |
| 1734 // The implementation details of the interpreter. | 1753 // The implementation details of the interpreter. |
| 1735 //============================================================================ | 1754 //============================================================================ |
| 1736 class WasmInterpreterInternals : public ZoneObject { | 1755 class WasmInterpreterInternals : public ZoneObject { |
| 1737 public: | 1756 public: |
| 1738 WasmInstance* instance_; | 1757 WasmInstance* instance_; |
| 1739 // Create a copy of the module bytes for the interpreter, since the passed | 1758 // Create a copy of the module bytes for the interpreter, since the passed |
| 1740 // pointer might be invalidated after constructing the interpreter. | 1759 // pointer might be invalidated after constructing the interpreter. |
| 1741 const ZoneVector<uint8_t> module_bytes_; | 1760 const ZoneVector<uint8_t> module_bytes_; |
| 1742 CodeMap codemap_; | 1761 CodeMap codemap_; |
| 1743 ZoneVector<WasmInterpreter::Thread> threads_; | 1762 ZoneVector<ThreadImpl> threads_; |
| 1744 | 1763 |
| 1745 WasmInterpreterInternals(Zone* zone, const ModuleBytesEnv& env) | 1764 WasmInterpreterInternals(Zone* zone, const ModuleBytesEnv& env) |
| 1746 : instance_(env.instance), | 1765 : instance_(env.instance), |
| 1747 module_bytes_(env.module_bytes.start(), env.module_bytes.end(), zone), | 1766 module_bytes_(env.module_bytes.start(), env.module_bytes.end(), zone), |
| 1748 codemap_(env.instance ? env.instance->module : nullptr, | 1767 codemap_(env.instance ? env.instance->module : nullptr, |
| 1749 module_bytes_.data(), zone), | 1768 module_bytes_.data(), zone), |
| 1750 threads_(zone) { | 1769 threads_(zone) { |
| 1751 threads_.push_back(WasmInterpreter::Thread( | 1770 threads_.push_back(ThreadImpl(zone, &codemap_, env.instance)); |
| 1752 new (zone) WasmInterpreter::ThreadImpl(zone, &codemap_, env.instance))); | |
| 1753 } | 1771 } |
| 1754 | 1772 |
| 1755 void Delete() { threads_.clear(); } | 1773 void Delete() { threads_.clear(); } |
| 1756 }; | 1774 }; |
| 1757 | 1775 |
| 1758 //============================================================================ | 1776 //============================================================================ |
| 1759 // Implementation of the public interface of the interpreter. | 1777 // Implementation of the public interface of the interpreter. |
| 1760 //============================================================================ | 1778 //============================================================================ |
| 1761 WasmInterpreter::WasmInterpreter(const ModuleBytesEnv& env, | 1779 WasmInterpreter::WasmInterpreter(const ModuleBytesEnv& env, |
| 1762 AccountingAllocator* allocator) | 1780 AccountingAllocator* allocator) |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1805 UNIMPLEMENTED(); | 1823 UNIMPLEMENTED(); |
| 1806 return false; | 1824 return false; |
| 1807 } | 1825 } |
| 1808 | 1826 |
| 1809 int WasmInterpreter::GetThreadCount() { | 1827 int WasmInterpreter::GetThreadCount() { |
| 1810 return 1; // only one thread for now. | 1828 return 1; // only one thread for now. |
| 1811 } | 1829 } |
| 1812 | 1830 |
| 1813 WasmInterpreter::Thread* WasmInterpreter::GetThread(int id) { | 1831 WasmInterpreter::Thread* WasmInterpreter::GetThread(int id) { |
| 1814 CHECK_EQ(0, id); // only one thread for now. | 1832 CHECK_EQ(0, id); // only one thread for now. |
| 1815 return &internals_->threads_[id]; | 1833 return ToThread(&internals_->threads_[id]); |
| 1816 } | 1834 } |
| 1817 | 1835 |
| 1818 WasmVal WasmInterpreter::GetLocalVal(const WasmFrame* frame, int index) { | 1836 WasmVal WasmInterpreter::GetLocalVal(const WasmFrame* frame, int index) { |
| 1819 CHECK_GE(index, 0); | 1837 CHECK_GE(index, 0); |
| 1820 UNIMPLEMENTED(); | 1838 UNIMPLEMENTED(); |
| 1821 WasmVal none; | 1839 WasmVal none; |
| 1822 none.type = kWasmStmt; | 1840 none.type = kWasmStmt; |
| 1823 return none; | 1841 return none; |
| 1824 } | 1842 } |
| 1825 | 1843 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1863 | 1881 |
| 1864 ControlTransferMap WasmInterpreter::ComputeControlTransfersForTesting( | 1882 ControlTransferMap WasmInterpreter::ComputeControlTransfersForTesting( |
| 1865 Zone* zone, const byte* start, const byte* end) { | 1883 Zone* zone, const byte* start, const byte* end) { |
| 1866 ControlTransfers targets(zone, nullptr, start, end); | 1884 ControlTransfers targets(zone, nullptr, start, end); |
| 1867 return targets.map_; | 1885 return targets.map_; |
| 1868 } | 1886 } |
| 1869 | 1887 |
| 1870 } // namespace wasm | 1888 } // namespace wasm |
| 1871 } // namespace internal | 1889 } // namespace internal |
| 1872 } // namespace v8 | 1890 } // namespace v8 |
| OLD | NEW |