Coverage Report

Created: 2025-07-01 06:18

/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