Coverage Report

Created: 2025-07-01 06:18

/src/WasmEdge/include/vm/vm.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/vm/vm.h - VM execution flow class definition -------------===//
5
//
6
// Part of the WasmEdge Project.
7
//
8
//===----------------------------------------------------------------------===//
9
///
10
/// \file
11
/// This file is the definition class of VM class.
12
///
13
//===----------------------------------------------------------------------===//
14
#pragma once
15
16
#include "common/async.h"
17
#include "common/configure.h"
18
#include "common/errcode.h"
19
#include "common/filesystem.h"
20
#include "common/types.h"
21
22
#include "executor/executor.h"
23
#include "loader/loader.h"
24
#include "validator/validator.h"
25
26
#include "runtime/instance/module.h"
27
#include "runtime/storemgr.h"
28
29
#include <cstdint>
30
#include <memory>
31
#include <shared_mutex>
32
#include <string>
33
#include <string_view>
34
#include <unordered_map>
35
#include <utility>
36
#include <vector>
37
38
namespace WasmEdge {
39
namespace VM {
40
41
/// VM execution flow class
42
class VM {
43
public:
44
  VM() = delete;
45
  VM(const Configure &Conf);
46
  VM(const Configure &Conf, Runtime::StoreManager &S);
47
0
  ~VM() = default;
48
49
  /// ======= Functions can be called before instantiated stage. =======
50
  /// Register wasm modules and host modules.
51
  Expect<void> registerModule(std::string_view Name,
52
0
                              const std::filesystem::path &Path) {
53
0
    std::unique_lock Lock(Mutex);
54
0
    return unsafeRegisterModule(Name, Path);
55
0
  }
56
0
  Expect<void> registerModule(std::string_view Name, Span<const Byte> Code) {
57
0
    std::unique_lock Lock(Mutex);
58
0
    return unsafeRegisterModule(Name, Code);
59
0
  }
60
  Expect<void> registerModule(std::string_view Name,
61
0
                              const AST::Module &Module) {
62
0
    std::unique_lock Lock(Mutex);
63
0
    return unsafeRegisterModule(Name, Module);
64
0
  }
65
  Expect<void>
66
0
  registerModule(const Runtime::Instance::ModuleInstance &ModInst) {
67
0
    std::unique_lock Lock(Mutex);
68
0
    return unsafeRegisterModule(ModInst);
69
0
  }
70
71
  /// Rapidly load, validate, instantiate, and run wasm function.
72
  Expect<std::vector<std::pair<ValVariant, ValType>>>
73
  runWasmFile(const std::filesystem::path &Path, std::string_view Func,
74
              Span<const ValVariant> Params = {},
75
0
              Span<const ValType> ParamTypes = {}) {
76
0
    std::unique_lock Lock(Mutex);
77
0
    return unsafeRunWasmFile(Path, Func, Params, ParamTypes);
78
0
  }
79
  Expect<std::vector<std::pair<ValVariant, ValType>>>
80
  runWasmFile(Span<const Byte> Code, std::string_view Func,
81
              Span<const ValVariant> Params = {},
82
0
              Span<const ValType> ParamTypes = {}) {
83
0
    std::unique_lock Lock(Mutex);
84
0
    return unsafeRunWasmFile(Code, Func, Params, ParamTypes);
85
0
  }
86
  Expect<std::vector<std::pair<ValVariant, ValType>>>
87
  runWasmFile(const AST::Module &Module, std::string_view Func,
88
              Span<const ValVariant> Params = {},
89
0
              Span<const ValType> ParamTypes = {}) {
90
0
    std::unique_lock Lock(Mutex);
91
0
    return unsafeRunWasmFile(Module, Func, Params, ParamTypes);
92
0
  }
93
94
  Async<Expect<std::vector<std::pair<ValVariant, ValType>>>>
95
  asyncRunWasmFile(const std::filesystem::path &Path, std::string_view Func,
96
                   Span<const ValVariant> Params = {},
97
                   Span<const ValType> ParamTypes = {});
98
  Async<Expect<std::vector<std::pair<ValVariant, ValType>>>>
99
  asyncRunWasmFile(Span<const Byte> Code, std::string_view Func,
100
                   Span<const ValVariant> Params = {},
101
                   Span<const ValType> ParamTypes = {});
102
  Async<Expect<std::vector<std::pair<ValVariant, ValType>>>>
103
  asyncRunWasmFile(const AST::Module &Module, std::string_view Func,
104
                   Span<const ValVariant> Params = {},
105
                   Span<const ValType> ParamTypes = {});
106
107
  /// Let runtimeTool can check which arguments should be prepared.
108
0
  bool holdsModule() {
109
0
    if (ActiveModInst) {
110
0
      return true;
111
0
    }
112
0
    return false;
113
0
  }
114
0
  bool holdsComponent() {
115
0
    if (ActiveCompInst) {
116
0
      return true;
117
0
    }
118
0
    return false;
119
0
  }
120
121
  /// Load given wasm file, wasm bytecode, or wasm module.
122
0
  Expect<void> loadWasm(const std::filesystem::path &Path) {
123
0
    std::unique_lock Lock(Mutex);
124
0
    return unsafeLoadWasm(Path);
125
0
  }
126
0
  Expect<void> loadWasm(Span<const Byte> Code) {
127
0
    std::unique_lock Lock(Mutex);
128
0
    return unsafeLoadWasm(Code);
129
0
  }
130
0
  Expect<void> loadWasm(const AST::Module &Module) {
131
0
    std::unique_lock Lock(Mutex);
132
0
    return unsafeLoadWasm(Module);
133
0
  }
134
135
  /// ======= Functions can be called after loaded stage. =======
136
  /// Validate loaded wasm module.
137
0
  Expect<void> validate() {
138
0
    std::unique_lock Lock(Mutex);
139
0
    return unsafeValidate();
140
0
  }
141
142
  /// ======= Functions can be called after validated stage. =======
143
  /// Instantiate validated wasm module.
144
0
  Expect<void> instantiate() {
145
0
    std::unique_lock Lock(Mutex);
146
0
    return unsafeInstantiate();
147
0
  }
148
149
  /// ======= Functions can be called after instantiated stage. =======
150
  /// Execute wasm with given input.
151
  Expect<std::vector<std::pair<ValVariant, ValType>>>
152
  execute(std::string_view Func, Span<const ValVariant> Params = {},
153
0
          Span<const ValType> ParamTypes = {}) {
154
0
    std::shared_lock Lock(Mutex);
155
0
    return unsafeExecute(Func, Params, ParamTypes);
156
0
  }
157
158
  Expect<std::vector<std::pair<ValInterface, ValType>>>
159
  execute(std::string_view Func, Span<const ValInterface> Params,
160
0
          Span<const ValType> ParamTypes) {
161
0
    std::shared_lock Lock(Mutex);
162
0
    return unsafeExecute(Func, Params, ParamTypes);
163
0
  }
164
165
  /// Execute function of registered module with given input.
166
  Expect<std::vector<std::pair<ValVariant, ValType>>>
167
  execute(std::string_view ModName, std::string_view Func,
168
          Span<const ValVariant> Params = {},
169
0
          Span<const ValType> ParamTypes = {}) {
170
0
    std::shared_lock Lock(Mutex);
171
0
    return unsafeExecute(ModName, Func, Params, ParamTypes);
172
0
  }
173
174
  /// Execute function of registered component with given input.
175
  Expect<std::vector<std::pair<ValInterface, ValType>>>
176
  execute(std::string_view CompName, std::string_view Func,
177
0
          Span<const ValInterface> Params, Span<const ValType> ParamTypes) {
178
0
    std::shared_lock Lock(Mutex);
179
0
    return unsafeExecute(CompName, Func, Params, ParamTypes);
180
0
  }
181
182
  /// Asynchronous execute wasm with given input.
183
  Async<Expect<std::vector<std::pair<ValVariant, ValType>>>>
184
  asyncExecute(std::string_view Func, Span<const ValVariant> Params = {},
185
               Span<const ValType> ParamTypes = {});
186
187
  /// Asynchronous execute function of registered module with given input.
188
  Async<Expect<std::vector<std::pair<ValVariant, ValType>>>>
189
  asyncExecute(std::string_view ModName, std::string_view Func,
190
               Span<const ValVariant> Params = {},
191
               Span<const ValType> ParamTypes = {});
192
193
  /// Asynchronous execute wasm with given input.
194
  Async<Expect<std::vector<std::pair<ValInterface, ValType>>>>
195
  asyncExecute(std::string_view Func, Span<const ValInterface> Params,
196
               Span<const ValType> ParamTypes);
197
198
  /// Asynchronous execute function of registered component with given input.
199
  Async<Expect<std::vector<std::pair<ValInterface, ValType>>>>
200
  asyncExecute(std::string_view ModName, std::string_view Func,
201
               Span<const ValInterface> Params, Span<const ValType> ParamTypes);
202
203
  /// Stop execution
204
0
  void stop() noexcept { ExecutorEngine.stop(); }
205
206
  /// ======= Functions which are stageless. =======
207
  /// Clean up VM status
208
0
  void cleanup() {
209
0
    std::unique_lock Lock(Mutex);
210
0
    return unsafeCleanup();
211
0
  }
212
213
  /// Get list of callable functions and corresponding function types.
214
  std::vector<std::pair<std::string, const AST::FunctionType &>>
215
0
  getFunctionList() const {
216
0
    std::shared_lock Lock(Mutex);
217
0
    return unsafeGetFunctionList();
218
0
  }
219
220
  /// Get pre-registered module instance by configuration.
221
  Runtime::Instance::ModuleInstance *
222
0
  getImportModule(const HostRegistration Type) const {
223
0
    std::shared_lock Lock(Mutex);
224
0
    return unsafeGetImportModule(Type);
225
0
  }
226
227
  /// Get current instantiated module instance.
228
0
  const Runtime::Instance::ModuleInstance *getActiveModule() const {
229
0
    std::shared_lock Lock(Mutex);
230
0
    return unsafeGetActiveModule();
231
0
  }
232
233
  /// Getter of store set in VM.
234
0
  Runtime::StoreManager &getStoreManager() noexcept { return StoreRef; }
235
0
  const Runtime::StoreManager &getStoreManager() const noexcept {
236
0
    return StoreRef;
237
0
  }
238
239
  /// Getter of loader in VM.
240
0
  Loader::Loader &getLoader() noexcept { return LoaderEngine; }
241
242
  /// Getter of validator in VM.
243
0
  Validator::Validator &getValidator() noexcept { return ValidatorEngine; }
244
245
  /// Getter of executor in VM.
246
0
  Executor::Executor &getExecutor() noexcept { return ExecutorEngine; }
247
248
  /// Getter of statistics.
249
0
  Statistics::Statistics &getStatistics() noexcept { return Stat; }
250
251
private:
252
  Expect<void> unsafeRegisterModule(std::string_view Name,
253
                                    const std::filesystem::path &Path);
254
  Expect<void> unsafeRegisterModule(std::string_view Name,
255
                                    Span<const Byte> Code);
256
  Expect<void> unsafeRegisterModule(std::string_view Name,
257
                                    const AST::Module &Module);
258
  Expect<void>
259
  unsafeRegisterModule(const Runtime::Instance::ModuleInstance &ModInst);
260
261
  Expect<std::vector<std::pair<ValVariant, ValType>>>
262
  unsafeRunWasmFile(const std::filesystem::path &Path, std::string_view Func,
263
                    Span<const ValVariant> Params = {},
264
                    Span<const ValType> ParamTypes = {});
265
  Expect<std::vector<std::pair<ValVariant, ValType>>>
266
  unsafeRunWasmFile(Span<const Byte> Code, std::string_view Func,
267
                    Span<const ValVariant> Params = {},
268
                    Span<const ValType> ParamTypes = {});
269
  Expect<std::vector<std::pair<ValVariant, ValType>>>
270
  unsafeRunWasmFile(const AST::Module &Module, std::string_view Func,
271
                    Span<const ValVariant> Params = {},
272
                    Span<const ValType> ParamTypes = {});
273
  Expect<std::vector<std::pair<ValVariant, ValType>>>
274
  unsafeRunWasmFile(const AST::Component::Component &Component,
275
                    std::string_view Func, Span<const ValVariant> Params = {},
276
                    Span<const ValType> ParamTypes = {});
277
278
  Expect<void> unsafeLoadWasm(const std::filesystem::path &Path);
279
  Expect<void> unsafeLoadWasm(Span<const Byte> Code);
280
  Expect<void> unsafeLoadWasm(const AST::Module &Module);
281
282
  Expect<void> unsafeValidate();
283
284
  Expect<void> unsafeInstantiate();
285
286
  Expect<std::vector<std::pair<ValVariant, ValType>>>
287
  unsafeExecute(std::string_view Func, Span<const ValVariant> Params = {},
288
                Span<const ValType> ParamTypes = {});
289
  Expect<std::vector<std::pair<ValVariant, ValType>>>
290
291
  unsafeExecute(std::string_view Mod, std::string_view Func,
292
                Span<const ValVariant> Params = {},
293
                Span<const ValType> ParamTypes = {});
294
295
  Expect<std::vector<std::pair<ValInterface, ValType>>>
296
  unsafeExecute(std::string_view Func, Span<const ValInterface> Params = {},
297
                Span<const ValType> ParamTypes = {});
298
299
  Expect<std::vector<std::pair<ValInterface, ValType>>>
300
  unsafeExecute(std::string_view Comp, std::string_view Func,
301
                Span<const ValInterface> Params = {},
302
                Span<const ValType> ParamTypes = {});
303
304
  void unsafeCleanup();
305
306
  std::vector<std::pair<std::string, const AST::FunctionType &>>
307
  unsafeGetFunctionList() const;
308
309
  Runtime::Instance::ModuleInstance *
310
  unsafeGetImportModule(const HostRegistration Type) const;
311
312
  const Runtime::Instance::ModuleInstance *unsafeGetActiveModule() const;
313
314
  enum class VMStage : uint8_t { Inited, Loaded, Validated, Instantiated };
315
316
  void unsafeInitVM();
317
  void unsafeLoadBuiltInHosts();
318
  void unsafeLoadPlugInHosts();
319
  void unsafeRegisterBuiltInHosts();
320
  void unsafeRegisterPlugInHosts();
321
322
  /// Helper function for execution.
323
  Expect<std::vector<std::pair<ValVariant, ValType>>>
324
  unsafeExecute(const Runtime::Instance::ModuleInstance *ModInst,
325
                std::string_view Func, Span<const ValVariant> Params = {},
326
                Span<const ValType> ParamTypes = {});
327
328
  Expect<std::vector<std::pair<ValInterface, ValType>>>
329
  unsafeExecute(const Runtime::Instance::ComponentInstance *CompInst,
330
                std::string_view Func, Span<const ValInterface> Params = {},
331
                Span<const ValType> ParamTypes = {});
332
333
  /// \name VM environment.
334
  /// @{
335
  const Configure Conf;
336
  Statistics::Statistics Stat;
337
  VMStage Stage;
338
  mutable std::shared_mutex Mutex;
339
  /// @}
340
341
  /// \name VM components.
342
  /// @{
343
  Loader::Loader LoaderEngine;
344
  Validator::Validator ValidatorEngine;
345
  Executor::Executor ExecutorEngine;
346
  /// @}
347
348
  /// \name VM Storage.
349
  /// @{
350
  /// Loaded AST module.
351
  std::unique_ptr<AST::Module> Mod;
352
  std::unique_ptr<AST::Component::Component> Comp;
353
  /// Active module instance.
354
  std::unique_ptr<Runtime::Instance::ModuleInstance> ActiveModInst;
355
  std::unique_ptr<Runtime::Instance::ComponentInstance> ActiveCompInst;
356
  /// Registered module instances by user.
357
  std::vector<std::unique_ptr<Runtime::Instance::ModuleInstance>> RegModInsts;
358
  /// Built-in module instances mapped to the configurations. For WASI.
359
  std::unordered_map<HostRegistration,
360
                     std::unique_ptr<Runtime::Instance::ModuleInstance>>
361
      BuiltInModInsts;
362
  /// Loaded module instances from plug-ins.
363
  std::vector<std::unique_ptr<Runtime::Instance::ModuleInstance>>
364
      PlugInModInsts;
365
  std::vector<std::unique_ptr<Runtime::Instance::ComponentInstance>>
366
      PlugInCompInsts;
367
  /// Self-owned store (nullptr if an outside store is assigned in constructor).
368
  std::unique_ptr<Runtime::StoreManager> Store;
369
  /// Reference to the store.
370
  Runtime::StoreManager &StoreRef;
371
  /// @}
372
};
373
374
} // namespace VM
375
} // namespace WasmEdge