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 |