Coverage Report

Created: 2025-12-31 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/include/vm/vm.h
Line
Count
Source
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
  /// Execute function of registered module with given input.
159
  Expect<std::vector<std::pair<ValVariant, ValType>>>
160
  execute(std::string_view ModName, std::string_view Func,
161
          Span<const ValVariant> Params = {},
162
0
          Span<const ValType> ParamTypes = {}) {
163
0
    std::shared_lock Lock(Mutex);
164
0
    return unsafeExecute(ModName, Func, Params, ParamTypes);
165
0
  }
166
167
  /// Execute component function with given input.
168
  Expect<std::vector<std::pair<ComponentValVariant, ComponentValType>>>
169
  executeComponent(std::string_view Func,
170
                   Span<const ComponentValVariant> Params = {},
171
0
                   Span<const ComponentValType> ParamTypes = {}) {
172
0
    std::shared_lock Lock(Mutex);
173
0
    return unsafeExecuteComponent(Func, Params, ParamTypes);
174
0
  }
175
176
  /// Execute function of registered component with given input.
177
  Expect<std::vector<std::pair<ComponentValVariant, ComponentValType>>>
178
  executeComponent(std::string_view CompName, std::string_view Func,
179
                   Span<const ComponentValVariant> Params = {},
180
0
                   Span<const ComponentValType> ParamTypes = {}) {
181
0
    std::shared_lock Lock(Mutex);
182
0
    return unsafeExecuteComponent(CompName, Func, Params, ParamTypes);
183
0
  }
184
185
  /// Asynchronous execute wasm with given input.
186
  Async<Expect<std::vector<std::pair<ValVariant, ValType>>>>
187
  asyncExecute(std::string_view Func, Span<const ValVariant> Params = {},
188
               Span<const ValType> ParamTypes = {});
189
190
  /// Asynchronous execute function of registered module with given input.
191
  Async<Expect<std::vector<std::pair<ValVariant, ValType>>>>
192
  asyncExecute(std::string_view ModName, std::string_view Func,
193
               Span<const ValVariant> Params = {},
194
               Span<const ValType> ParamTypes = {});
195
196
  /// Asynchronous execute component function with given input.
197
  Async<Expect<std::vector<std::pair<ComponentValVariant, ComponentValType>>>>
198
  asyncExecuteComponent(std::string_view Func,
199
                        Span<const ComponentValVariant> Params = {},
200
                        Span<const ComponentValType> ParamTypes = {});
201
202
  /// Asynchronous execute function of registered component with given input.
203
  Async<Expect<std::vector<std::pair<ComponentValVariant, ComponentValType>>>>
204
  asyncExecuteComponent(std::string_view ModName, std::string_view Func,
205
                        Span<const ComponentValVariant> Params = {},
206
                        Span<const ComponentValType> ParamTypes = {});
207
208
  /// Stop execution
209
0
  void stop() noexcept { ExecutorEngine.stop(); }
210
211
  /// ======= Functions which are stageless. =======
212
  /// Clean up VM status
213
0
  void cleanup() {
214
0
    std::unique_lock Lock(Mutex);
215
0
    return unsafeCleanup();
216
0
  }
217
218
  /// Get list of callable functions and corresponding function types.
219
  std::vector<std::pair<std::string, const AST::FunctionType &>>
220
0
  getFunctionList() const {
221
0
    std::shared_lock Lock(Mutex);
222
0
    return unsafeGetFunctionList();
223
0
  }
224
225
  /// Get list of callable component functions and corresponding function types.
226
  std::vector<std::pair<std::string, const AST::Component::FuncType &>>
227
0
  getComponentFunctionList() const {
228
0
    std::shared_lock Lock(Mutex);
229
0
    return unsafeGetComponentFunctionList();
230
0
  }
231
232
  /// Get pre-registered module instance by configuration.
233
  Runtime::Instance::ModuleInstance *
234
0
  getImportModule(const HostRegistration Type) const {
235
0
    std::shared_lock Lock(Mutex);
236
0
    return unsafeGetImportModule(Type);
237
0
  }
238
239
  /// Get current instantiated module instance.
240
0
  const Runtime::Instance::ModuleInstance *getActiveModule() const {
241
0
    std::shared_lock Lock(Mutex);
242
0
    return unsafeGetActiveModule();
243
0
  }
244
245
  /// Getter of store set in VM.
246
0
  Runtime::StoreManager &getStoreManager() noexcept { return StoreRef; }
247
0
  const Runtime::StoreManager &getStoreManager() const noexcept {
248
0
    return StoreRef;
249
0
  }
250
251
  /// Getter of loader in VM.
252
0
  Loader::Loader &getLoader() noexcept { return LoaderEngine; }
253
254
  /// Getter of validator in VM.
255
0
  Validator::Validator &getValidator() noexcept { return ValidatorEngine; }
256
257
  /// Getter of executor in VM.
258
0
  Executor::Executor &getExecutor() noexcept { return ExecutorEngine; }
259
260
  /// Getter of statistics.
261
0
  Statistics::Statistics &getStatistics() noexcept { return Stat; }
262
263
private:
264
  Expect<void> unsafeRegisterModule(std::string_view Name,
265
                                    const std::filesystem::path &Path);
266
  Expect<void> unsafeRegisterModule(std::string_view Name,
267
                                    Span<const Byte> Code);
268
  Expect<void> unsafeRegisterModule(std::string_view Name,
269
                                    const AST::Module &Module);
270
  Expect<void>
271
  unsafeRegisterModule(const Runtime::Instance::ModuleInstance &ModInst);
272
273
  Expect<std::vector<std::pair<ValVariant, ValType>>>
274
  unsafeRunWasmFile(const std::filesystem::path &Path, std::string_view Func,
275
                    Span<const ValVariant> Params = {},
276
                    Span<const ValType> ParamTypes = {});
277
  Expect<std::vector<std::pair<ValVariant, ValType>>>
278
  unsafeRunWasmFile(Span<const Byte> Code, std::string_view Func,
279
                    Span<const ValVariant> Params = {},
280
                    Span<const ValType> ParamTypes = {});
281
  Expect<std::vector<std::pair<ValVariant, ValType>>>
282
  unsafeRunWasmFile(const AST::Module &Module, std::string_view Func,
283
                    Span<const ValVariant> Params = {},
284
                    Span<const ValType> ParamTypes = {});
285
  Expect<std::vector<std::pair<ValVariant, ValType>>>
286
  unsafeRunWasmFile(const AST::Component::Component &Component,
287
                    std::string_view Func, Span<const ValVariant> Params = {},
288
                    Span<const ValType> ParamTypes = {});
289
290
  Expect<void> unsafeLoadWasm(const std::filesystem::path &Path);
291
  Expect<void> unsafeLoadWasm(Span<const Byte> Code);
292
  Expect<void> unsafeLoadWasm(const AST::Module &Module);
293
294
  Expect<void> unsafeValidate();
295
296
  Expect<void> unsafeInstantiate();
297
298
  Expect<std::vector<std::pair<ValVariant, ValType>>>
299
  unsafeExecute(std::string_view Func, Span<const ValVariant> Params = {},
300
                Span<const ValType> ParamTypes = {});
301
  Expect<std::vector<std::pair<ValVariant, ValType>>>
302
303
  unsafeExecute(std::string_view Mod, std::string_view Func,
304
                Span<const ValVariant> Params = {},
305
                Span<const ValType> ParamTypes = {});
306
307
  Expect<std::vector<std::pair<ComponentValVariant, ComponentValType>>>
308
  unsafeExecuteComponent(std::string_view Func,
309
                         Span<const ComponentValVariant> Params = {},
310
                         Span<const ComponentValType> ParamTypes = {});
311
312
  Expect<std::vector<std::pair<ComponentValVariant, ComponentValType>>>
313
  unsafeExecuteComponent(std::string_view Comp, std::string_view Func,
314
                         Span<const ComponentValVariant> Params = {},
315
                         Span<const ComponentValType> ParamTypes = {});
316
317
  void unsafeCleanup();
318
319
  std::vector<std::pair<std::string, const AST::FunctionType &>>
320
  unsafeGetFunctionList() const;
321
322
  std::vector<std::pair<std::string, const AST::Component::FuncType &>>
323
  unsafeGetComponentFunctionList() const;
324
325
  Runtime::Instance::ModuleInstance *
326
  unsafeGetImportModule(const HostRegistration Type) const;
327
328
  const Runtime::Instance::ModuleInstance *unsafeGetActiveModule() const;
329
330
  enum class VMStage : uint8_t { Inited, Loaded, Validated, Instantiated };
331
332
  void unsafeInitVM();
333
  void unsafeLoadBuiltInHosts();
334
  void unsafeLoadPlugInHosts();
335
  void unsafeRegisterBuiltInHosts();
336
  void unsafeRegisterPlugInHosts();
337
338
  /// Helper function for execution.
339
  Expect<std::vector<std::pair<ValVariant, ValType>>>
340
  unsafeExecute(const Runtime::Instance::ModuleInstance *ModInst,
341
                std::string_view Func, Span<const ValVariant> Params = {},
342
                Span<const ValType> ParamTypes = {});
343
344
  Expect<std::vector<std::pair<ComponentValVariant, ComponentValType>>>
345
  unsafeExecuteComponent(const Runtime::Instance::ComponentInstance *CompInst,
346
                         std::string_view Func,
347
                         Span<const ComponentValVariant> Params = {},
348
                         Span<const ComponentValType> ParamTypes = {});
349
350
  /// \name VM environment.
351
  /// @{
352
  const Configure Conf;
353
  Statistics::Statistics Stat;
354
  VMStage Stage;
355
  mutable std::shared_mutex Mutex;
356
  /// @}
357
358
  /// \name VM components.
359
  /// @{
360
  Loader::Loader LoaderEngine;
361
  Validator::Validator ValidatorEngine;
362
  Executor::Executor ExecutorEngine;
363
  /// @}
364
365
  /// \name VM Storage.
366
  /// @{
367
  /// Loaded AST module.
368
  std::unique_ptr<AST::Module> Mod;
369
  std::unique_ptr<AST::Component::Component> Comp;
370
  /// Active module instance.
371
  std::unique_ptr<Runtime::Instance::ModuleInstance> ActiveModInst;
372
  std::unique_ptr<Runtime::Instance::ComponentInstance> ActiveCompInst;
373
  /// Registered module instances by user.
374
  std::vector<std::unique_ptr<Runtime::Instance::ModuleInstance>> RegModInsts;
375
  /// Built-in module instances mapped to the configurations. For WASI.
376
  std::unordered_map<HostRegistration,
377
                     std::unique_ptr<Runtime::Instance::ModuleInstance>>
378
      BuiltInModInsts;
379
  /// Loaded module instances from plug-ins.
380
  std::vector<std::unique_ptr<Runtime::Instance::ModuleInstance>>
381
      PlugInModInsts;
382
  std::vector<std::unique_ptr<Runtime::Instance::ComponentInstance>>
383
      PlugInCompInsts;
384
  /// Self-owned store (nullptr if an outside store is assigned in constructor).
385
  std::unique_ptr<Runtime::StoreManager> Store;
386
  /// Reference to the store.
387
  Runtime::StoreManager &StoreRef;
388
  /// @}
389
};
390
391
} // namespace VM
392
} // namespace WasmEdge