/src/WasmEdge/include/plugin/plugin.h
Line | Count | Source (jump to first uncovered line) |
1 | | // SPDX-License-Identifier: Apache-2.0 |
2 | | // SPDX-FileCopyrightText: 2019-2024 Second State INC |
3 | | |
4 | | //===-- wasmedge/plugin/plugin.h - Plugin class definition ----------------===// |
5 | | // |
6 | | // Part of the WasmEdge Project. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | /// |
10 | | /// \file |
11 | | /// This file is the definition class of Plugin class. |
12 | | /// |
13 | | //===----------------------------------------------------------------------===// |
14 | | #pragma once |
15 | | |
16 | | #include "common/defines.h" |
17 | | #include "common/filesystem.h" |
18 | | #include "common/hash.h" |
19 | | #include "common/version.h" |
20 | | #include "loader/shared_library.h" |
21 | | #include "po/argument_parser.h" |
22 | | #include "runtime/instance/component.h" |
23 | | #include "runtime/instance/module.h" |
24 | | |
25 | | #include <cstdint> |
26 | | #include <memory> |
27 | | #include <mutex> |
28 | | #include <vector> |
29 | | |
30 | | #define EXPORT_GET_DESCRIPTOR(Descriptor) \ |
31 | | extern "C" WASMEDGE_EXPORT decltype(&Descriptor) GetDescriptor(); \ |
32 | | extern "C" WASMEDGE_EXPORT decltype(&Descriptor) GetDescriptor() { \ |
33 | | return &Descriptor; \ |
34 | | } |
35 | | |
36 | | namespace WasmEdge { |
37 | | namespace Plugin { |
38 | | |
39 | | class PluginModule { |
40 | | public: |
41 | | PluginModule(const PluginModule &) = delete; |
42 | | PluginModule &operator=(const PluginModule &) = delete; |
43 | | PluginModule(PluginModule &&) noexcept = default; |
44 | | PluginModule &operator=(PluginModule &&) noexcept = default; |
45 | | |
46 | | struct ModuleDescriptor { |
47 | | const char *Name; |
48 | | const char *Description; |
49 | | Runtime::Instance::ModuleInstance *(*Create)( |
50 | | const ModuleDescriptor *) noexcept; |
51 | | }; |
52 | | |
53 | 0 | constexpr PluginModule() noexcept {} |
54 | | |
55 | 0 | constexpr const char *name() const noexcept { |
56 | 0 | assuming(Desc); |
57 | 0 | return Desc->Name; |
58 | 0 | } |
59 | | |
60 | 0 | constexpr const char *description() const noexcept { |
61 | 0 | assuming(Desc); |
62 | 0 | return Desc->Description; |
63 | 0 | } |
64 | | |
65 | 0 | std::unique_ptr<Runtime::Instance::ModuleInstance> create() const noexcept { |
66 | 0 | assuming(Desc); |
67 | 0 | return std::unique_ptr<Runtime::Instance::ModuleInstance>( |
68 | 0 | Desc->Create(Desc)); |
69 | 0 | } |
70 | | |
71 | | private: |
72 | | const ModuleDescriptor *Desc = nullptr; |
73 | | |
74 | | constexpr explicit PluginModule(const ModuleDescriptor *D) noexcept |
75 | 0 | : Desc(D) {} |
76 | | friend class Plugin; |
77 | | }; |
78 | | |
79 | | class PluginComponent { |
80 | | public: |
81 | | PluginComponent(const PluginComponent &) = delete; |
82 | | PluginComponent &operator=(const PluginComponent &) = delete; |
83 | | PluginComponent(PluginComponent &&) noexcept = default; |
84 | | PluginComponent &operator=(PluginComponent &&) noexcept = default; |
85 | | |
86 | | struct ComponentDescriptor { |
87 | | const char *Name; |
88 | | const char *Description; |
89 | | Runtime::Instance::ComponentInstance *(*Create)( |
90 | | const ComponentDescriptor *) noexcept; |
91 | | }; |
92 | | |
93 | 0 | constexpr PluginComponent() noexcept {} |
94 | | |
95 | 0 | constexpr const char *name() const noexcept { |
96 | 0 | assuming(Desc); |
97 | 0 | return Desc->Name; |
98 | 0 | } |
99 | | |
100 | 0 | constexpr const char *description() const noexcept { |
101 | 0 | assuming(Desc); |
102 | 0 | return Desc->Description; |
103 | 0 | } |
104 | | |
105 | | std::unique_ptr<Runtime::Instance::ComponentInstance> |
106 | 0 | create() const noexcept { |
107 | 0 | assuming(Desc); |
108 | 0 | return std::unique_ptr<Runtime::Instance::ComponentInstance>( |
109 | 0 | Desc->Create(Desc)); |
110 | 0 | } |
111 | | |
112 | | private: |
113 | | const ComponentDescriptor *Desc = nullptr; |
114 | | |
115 | | constexpr explicit PluginComponent(const ComponentDescriptor *D) noexcept |
116 | 0 | : Desc(D) {} |
117 | | friend class Plugin; |
118 | | }; |
119 | | |
120 | | class Plugin { |
121 | | public: |
122 | | struct VersionData { |
123 | | uint32_t Major; |
124 | | uint32_t Minor; |
125 | | uint32_t Patch; |
126 | | uint32_t Build; |
127 | | }; |
128 | | struct PluginDescriptor { |
129 | | const char *Name; |
130 | | const char *Description; |
131 | | uint32_t APIVersion; |
132 | | VersionData Version; |
133 | | size_t ModuleCount; |
134 | | PluginModule::ModuleDescriptor *ModuleDescriptions; |
135 | | size_t ComponentCount = 0; |
136 | | PluginComponent::ComponentDescriptor *ComponentDescriptions = nullptr; |
137 | | void (*AddOptions)(const PluginDescriptor *D, |
138 | | PO::ArgumentParser &Parser) noexcept; |
139 | | }; |
140 | | |
141 | | // Const value of current plugin API version. |
142 | | static inline constexpr const uint32_t CurrentAPIVersion [[maybe_unused]] = |
143 | | kPluginCurrentAPIVersion; |
144 | | |
145 | | // Static function to load plugins from default paths. |
146 | | WASMEDGE_EXPORT static void loadFromDefaultPaths() noexcept; |
147 | | |
148 | | // Static function to get default plugin paths. |
149 | | static std::vector<std::filesystem::path> getDefaultPluginPaths() noexcept; |
150 | | |
151 | | // Static function to load all plugins from given path. |
152 | | WASMEDGE_EXPORT static bool load(const std::filesystem::path &Path) noexcept; |
153 | | |
154 | | // Static function to register plugin with descriptor. |
155 | | static bool registerPlugin(const PluginDescriptor *Desc) noexcept; |
156 | | |
157 | | // Static function to add plugin options from arguments. |
158 | | static void addPluginOptions(PO::ArgumentParser &Parser) noexcept; |
159 | | |
160 | | // Static function to find loaded plugin by name. |
161 | | WASMEDGE_EXPORT static const Plugin *find(std::string_view Name) noexcept; |
162 | | |
163 | | // Static function to list loaded plugins. |
164 | | static Span<const Plugin> plugins() noexcept; |
165 | | |
166 | | Plugin(const Plugin &) = delete; |
167 | | Plugin &operator=(const Plugin &) = delete; |
168 | 0 | Plugin(Plugin &&) noexcept = default; |
169 | | Plugin &operator=(Plugin &&) noexcept = default; |
170 | | |
171 | | Plugin() noexcept = default; |
172 | | explicit Plugin(const PluginDescriptor *D) noexcept; |
173 | | |
174 | 0 | constexpr const char *name() const noexcept { |
175 | 0 | assuming(Desc); |
176 | 0 | return Desc->Name; |
177 | 0 | } |
178 | | |
179 | 0 | constexpr const char *description() const noexcept { |
180 | 0 | assuming(Desc); |
181 | 0 | return Desc->Description; |
182 | 0 | } |
183 | | |
184 | 0 | constexpr VersionData version() const noexcept { |
185 | 0 | assuming(Desc); |
186 | 0 | return Desc->Version; |
187 | 0 | } |
188 | | |
189 | 0 | void registerOptions(PO::ArgumentParser &Parser) const noexcept { |
190 | 0 | assuming(Desc); |
191 | 0 | if (Desc->AddOptions) { |
192 | 0 | Desc->AddOptions(Desc, Parser); |
193 | 0 | } |
194 | 0 | } |
195 | | |
196 | 0 | Span<const PluginModule> modules() const noexcept { |
197 | 0 | assuming(Desc); |
198 | 0 | return ModuleRegistry; |
199 | 0 | } |
200 | 0 | Span<const PluginComponent> components() const noexcept { |
201 | 0 | assuming(Desc); |
202 | 0 | return ComponentRegistry; |
203 | 0 | } |
204 | | |
205 | | WASMEDGE_EXPORT const PluginModule * |
206 | | findModule(std::string_view Name) const noexcept; |
207 | | |
208 | | WASMEDGE_EXPORT const PluginComponent * |
209 | | findComponent(std::string_view Name) const noexcept; |
210 | | |
211 | 0 | std::filesystem::path path() const noexcept { return Path; } |
212 | | |
213 | | private: |
214 | | static std::mutex Mutex; |
215 | | static std::vector<Plugin> PluginRegistry; |
216 | | static std::unordered_map<std::string_view, std::size_t, Hash::Hash> |
217 | | PluginNameLookup; |
218 | | |
219 | | // Static function to load plugin from file. Thread-safe. |
220 | | static bool loadFile(const std::filesystem::path &Path) noexcept; |
221 | | |
222 | | // Static function to register built-in plugins. Thread-safe. |
223 | | static void registerBuiltInPlugins() noexcept; |
224 | | |
225 | | // Plugin contents. |
226 | | std::filesystem::path Path; |
227 | | const PluginDescriptor *Desc = nullptr; |
228 | | std::shared_ptr<Loader::SharedLibrary> Lib; |
229 | | std::vector<PluginModule> ModuleRegistry; |
230 | | std::vector<PluginComponent> ComponentRegistry; |
231 | | std::unordered_map<std::string_view, std::size_t, Hash::Hash> |
232 | | ModuleNameLookup; |
233 | | std::unordered_map<std::string_view, std::size_t, Hash::Hash> |
234 | | ComponentNameLookup; |
235 | | }; |
236 | | |
237 | | } // namespace Plugin |
238 | | } // namespace WasmEdge |