Coverage Report

Created: 2026-11-12 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/include/runtime/instance/module.h
Line
Count
Source
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright The WasmEdge Authors
3
4
//===-- wasmedge/runtime/instance/module.h - Module Instance definition ---===//
5
//
6
// Part of the WasmEdge Project.
7
//
8
//===----------------------------------------------------------------------===//
9
///
10
/// \file
11
/// This file contains the module instance definition in store manager.
12
///
13
//===----------------------------------------------------------------------===//
14
#pragma once
15
16
#include "ast/component/component.h"
17
#include "ast/module.h"
18
#include "common/errcode.h"
19
#include "runtime/hostfunc.h"
20
#include "runtime/instance/array.h"
21
#include "runtime/instance/data.h"
22
#include "runtime/instance/elem.h"
23
#include "runtime/instance/exception.h"
24
#include "runtime/instance/function.h"
25
#include "runtime/instance/global.h"
26
#include "runtime/instance/memory.h"
27
#include "runtime/instance/reflifetime.h"
28
#include "runtime/instance/struct.h"
29
#include "runtime/instance/table.h"
30
#include "runtime/instance/tag.h"
31
32
#include <atomic>
33
#include <cstddef>
34
#include <functional>
35
#include <map>
36
#include <memory>
37
#include <mutex>
38
#include <set>
39
#include <shared_mutex>
40
#include <string>
41
#include <type_traits>
42
#include <unordered_set>
43
#include <vector>
44
45
namespace WasmEdge {
46
47
namespace Executor {
48
class Executor;
49
}
50
51
namespace Runtime {
52
53
class StoreManager;
54
class CallingFrame;
55
56
namespace Instance {
57
58
namespace {
59
/// Return true if T is an entity that can be exported or imported.
60
template <typename T>
61
inline constexpr const bool IsEntityV =
62
    std::is_same_v<T, Instance::FunctionInstance> ||
63
    std::is_same_v<T, Instance::TableInstance> ||
64
    std::is_same_v<T, Instance::MemoryInstance> ||
65
    std::is_same_v<T, Instance::GlobalInstance> ||
66
    std::is_same_v<T, Instance::TagInstance>;
67
68
/// Return true if T is an instance.
69
template <typename T>
70
inline constexpr const bool IsInstanceV =
71
    IsEntityV<T> || std::is_same_v<T, Instance::ElementInstance> ||
72
    std::is_same_v<T, Instance::DataInstance>;
73
} // namespace
74
75
class ComponentInstance;
76
77
/// Module instances use a dependency-pinned lifetime: each importer pins the
78
/// instances it imports from (see RefLifetime) and releases them when
79
/// destroyed, so a heap instance torn down via terminate() is deleted only
80
/// after its owner and all importers release.
81
///
82
/// A stack- or member-allocated provider cannot be deferred by a pin, so it
83
/// must outlive its importers: declare a host module before the VM or
84
/// StoreManager that imports it. The destructor enforces this with
85
/// assuming(!hasDependents()).
86
class ModuleInstance {
87
public:
88
  ModuleInstance(std::string_view Name, void *Data = nullptr,
89
                 std::function<void(void *)> Finalizer = nullptr)
90
0
      : ModName(Name), HostData(Data), HostDataFinalizer(Finalizer) {}
91
0
  virtual ~ModuleInstance() noexcept {
92
    // Fallback for instances torn down outside terminate() (e.g.
93
    // stack-allocated).
94
0
    unlinkAllStores();
95
0
    assuming(!Life.hasDependents());
96
0
    if (HostDataFinalizer.operator bool()) {
97
0
      HostDataFinalizer(HostData);
98
0
    }
99
0
    releaseProviders();
100
0
  }
101
102
0
  void terminate() noexcept {
103
0
    unlinkAllStores();
104
0
    if (Life.releaseOwner()) {
105
0
      delete this;
106
0
    }
107
0
  }
108
109
  /// Mark this module instance finalized (immutable). Idempotent, thread-safe.
110
0
  void finalizeInstantiation() const noexcept {
111
0
    if (InstantiateFinalized.load(std::memory_order_acquire)) {
112
0
      return;
113
0
    }
114
0
    std::unique_lock Lock(Mutex);
115
0
    InstantiateFinalized.store(true, std::memory_order_release);
116
0
  }
117
118
  /// Return true if this module instance has been finalized (immutable).
119
0
  bool isInstantiateFinalized() const noexcept {
120
0
    return InstantiateFinalized.load(std::memory_order_acquire);
121
0
  }
122
123
0
  std::string_view getModuleName() const noexcept {
124
0
    std::shared_lock Lock(Mutex);
125
0
    return ModName;
126
0
  }
127
128
0
  void *getHostData() const noexcept { return HostData; }
129
130
  /// Get the defined type by index.
131
0
  Expect<const AST::SubType *> getType(uint32_t Idx) const noexcept {
132
0
    std::shared_lock Lock(Mutex);
133
0
    if (unlikely(Idx >= Types.size())) {
134
      // Error logging needs to be handled by the caller.
135
0
      return Unexpect(ErrCode::Value::WrongInstanceIndex);
136
0
    }
137
0
    return unsafeGetType(Idx);
138
0
  }
139
140
  /// Get defined type list.
141
0
  Span<const AST::SubType *const> getTypeList() const noexcept { return Types; }
142
143
0
  Span<const FunctionInstance *const> getFunctionInstances() const noexcept {
144
0
    return Span<const FunctionInstance *const>(
145
0
        const_cast<const FunctionInstance *const *>(FuncInsts.data()),
146
0
        FuncInsts.size());
147
0
  }
148
149
0
  Span<const MemoryInstance *const> getMemoryInstances() const noexcept {
150
0
    return Span<const MemoryInstance *const>(
151
0
        const_cast<const MemoryInstance *const *>(MemInsts.data()),
152
0
        MemInsts.size());
153
0
  }
154
155
0
  Span<MemoryInstance *const> getMemoryInstances() noexcept { return MemInsts; }
156
157
0
  Span<const GlobalInstance *const> getGlobalInstances() const noexcept {
158
0
    return Span<const GlobalInstance *const>(
159
0
        const_cast<const GlobalInstance *const *>(GlobInsts.data()),
160
0
        GlobInsts.size());
161
0
  }
162
163
0
  Span<GlobalInstance *const> getGlobalInstances() noexcept {
164
0
    return GlobInsts;
165
0
  }
166
167
0
  Span<const TableInstance *const> getTableInstances() const noexcept {
168
0
    return Span<const TableInstance *const>(
169
0
        const_cast<const TableInstance *const *>(TabInsts.data()),
170
0
        TabInsts.size());
171
0
  }
172
173
0
  Span<TableInstance *const> getTableInstances() noexcept { return TabInsts; }
174
175
0
  Span<const ElementInstance *const> getElemInstances() const noexcept {
176
0
    return Span<const ElementInstance *const>(
177
0
        const_cast<const ElementInstance *const *>(ElemInsts.data()),
178
0
        ElemInsts.size());
179
0
  }
180
181
0
  Span<ElementInstance *const> getElemInstances() noexcept { return ElemInsts; }
182
183
0
  Span<const DataInstance *const> getOwnedDataInstances() const noexcept {
184
0
    return Span<const DataInstance *const>(
185
0
        const_cast<const DataInstance *const *>(DataInsts.data()),
186
0
        DataInsts.size());
187
0
  }
188
189
0
  Span<DataInstance *const> getOwnedDataInstances() noexcept {
190
0
    return DataInsts;
191
0
  }
192
193
  /// Check whether this module instance owns the instance.
194
0
  bool owns(const TableInstance *Instance) const noexcept {
195
0
    return std::any_of(
196
0
        OwnedTabInsts.begin(), OwnedTabInsts.end(),
197
0
        [Instance](const auto &Owned) { return Owned.get() == Instance; });
198
0
  }
199
0
  bool owns(const GlobalInstance *Instance) const noexcept {
200
0
    return std::any_of(
201
0
        OwnedGlobInsts.begin(), OwnedGlobInsts.end(),
202
0
        [Instance](const auto &Owned) { return Owned.get() == Instance; });
203
0
  }
204
205
  /// Add existing instances and move ownership with the export name.
206
  ///
207
  /// These functions fail with `ErrCode::Value::WrongVMWorkflow` if the module
208
  /// instance has already been finalized, i.e. it has been used during
209
  /// execution and become immutable. On failure the passed-in `unique_ptr` is
210
  /// not moved from, so the caller retains ownership of the instance.
211
  Expect<void> addHostFunc(std::string_view Name,
212
0
                           std::unique_ptr<HostFunctionBase> &&Func) {
213
0
    std::unique_lock Lock(Mutex);
214
0
    if (unlikely(InstantiateFinalized.load(std::memory_order_acquire))) {
215
0
      return Unexpect(ErrCode::Value::WrongVMWorkflow);
216
0
    }
217
0
    unsafeImportDefinedType(Func->getDefinedType());
218
0
    unsafeAddHostInstance(
219
0
        Name, OwnedFuncInsts, FuncInsts, ExpFuncs,
220
0
        std::make_unique<FunctionInstance>(
221
0
            this, static_cast<uint32_t>(Types.size()) - 1, std::move(Func)));
222
0
    return {};
223
0
  }
224
  Expect<void> addHostFunc(std::string_view Name,
225
0
                           std::unique_ptr<FunctionInstance> &&Func) {
226
0
    std::unique_lock Lock(Mutex);
227
0
    if (unlikely(InstantiateFinalized.load(std::memory_order_acquire))) {
228
0
      return Unexpect(ErrCode::Value::WrongVMWorkflow);
229
0
    }
230
0
    assuming(Func->isHostFunction());
231
0
    unsafeImportDefinedType(Func->getHostFunc().getDefinedType());
232
0
    Func->linkDefinedType(this, static_cast<uint32_t>(Types.size()) - 1);
233
0
    unsafeAddHostInstance(Name, OwnedFuncInsts, FuncInsts, ExpFuncs,
234
0
                          std::move(Func));
235
0
    return {};
236
0
  }
237
238
  Expect<void> addHostTable(std::string_view Name,
239
0
                            std::unique_ptr<TableInstance> &&Tab) {
240
0
    std::unique_lock Lock(Mutex);
241
0
    if (unlikely(InstantiateFinalized.load(std::memory_order_acquire))) {
242
0
      return Unexpect(ErrCode::Value::WrongVMWorkflow);
243
0
    }
244
0
    unsafeAddHostInstance(Name, OwnedTabInsts, TabInsts, ExpTables,
245
0
                          std::move(Tab));
246
0
    return {};
247
0
  }
248
  Expect<void> addHostMemory(std::string_view Name,
249
0
                             std::unique_ptr<MemoryInstance> &&Mem) {
250
0
    std::unique_lock Lock(Mutex);
251
0
    if (unlikely(InstantiateFinalized.load(std::memory_order_acquire))) {
252
0
      return Unexpect(ErrCode::Value::WrongVMWorkflow);
253
0
    }
254
0
    unsafeAddHostInstance(Name, OwnedMemInsts, MemInsts, ExpMems,
255
0
                          std::move(Mem));
256
0
    return {};
257
0
  }
258
  Expect<void> addHostGlobal(std::string_view Name,
259
0
                             std::unique_ptr<GlobalInstance> &&Glob) {
260
0
    std::unique_lock Lock(Mutex);
261
0
    if (unlikely(InstantiateFinalized.load(std::memory_order_acquire))) {
262
0
      return Unexpect(ErrCode::Value::WrongVMWorkflow);
263
0
    }
264
0
    unsafeAddHostInstance(Name, OwnedGlobInsts, GlobInsts, ExpGlobals,
265
0
                          std::move(Glob));
266
0
    return {};
267
0
  }
268
269
  /// Find and get the exported instance by name.
270
0
  FunctionInstance *findFuncExports(std::string_view ExtName) const noexcept {
271
0
    std::shared_lock Lock(Mutex);
272
0
    return unsafeFindExports(ExpFuncs, ExtName);
273
0
  }
274
0
  TableInstance *findTableExports(std::string_view ExtName) const noexcept {
275
0
    std::shared_lock Lock(Mutex);
276
0
    return unsafeFindExports(ExpTables, ExtName);
277
0
  }
278
0
  MemoryInstance *findMemoryExports(std::string_view ExtName) const noexcept {
279
0
    std::shared_lock Lock(Mutex);
280
0
    return unsafeFindExports(ExpMems, ExtName);
281
0
  }
282
0
  TagInstance *findTagExports(std::string_view ExtName) const noexcept {
283
0
    std::shared_lock Lock(Mutex);
284
0
    return unsafeFindExports(ExpTags, ExtName);
285
0
  }
286
0
  GlobalInstance *findGlobalExports(std::string_view ExtName) const noexcept {
287
0
    std::shared_lock Lock(Mutex);
288
0
    return unsafeFindExports(ExpGlobals, ExtName);
289
0
  }
290
291
  /// Get the exported instances count.
292
0
  uint32_t getFuncExportNum() const noexcept {
293
0
    std::shared_lock Lock(Mutex);
294
0
    return static_cast<uint32_t>(ExpFuncs.size());
295
0
  }
296
0
  uint32_t getTableExportNum() const noexcept {
297
0
    std::shared_lock Lock(Mutex);
298
0
    return static_cast<uint32_t>(ExpTables.size());
299
0
  }
300
0
  uint32_t getMemoryExportNum() const noexcept {
301
0
    std::shared_lock Lock(Mutex);
302
0
    return static_cast<uint32_t>(ExpMems.size());
303
0
  }
304
0
  uint32_t getTagExportNum() const noexcept {
305
0
    std::shared_lock Lock(Mutex);
306
0
    return static_cast<uint32_t>(ExpTags.size());
307
0
  }
308
0
  uint32_t getGlobalExportNum() const noexcept {
309
0
    std::shared_lock Lock(Mutex);
310
0
    return static_cast<uint32_t>(ExpGlobals.size());
311
0
  }
312
313
  /// Get the exported instances maps.
314
  template <typename CallbackT>
315
0
  auto getFuncExports(CallbackT &&CallBack) const noexcept {
316
0
    std::shared_lock Lock(Mutex);
317
0
    return std::forward<CallbackT>(CallBack)(ExpFuncs);
318
0
  }
Unexecuted instantiation: wasmedge.cpp:auto WasmEdge::Runtime::Instance::ModuleInstance::getFuncExports<WasmEdge_ModuleInstanceListFunction::$_0>(WasmEdge_ModuleInstanceListFunction::$_0&&) const
Unexecuted instantiation: wasmedge.cpp:auto WasmEdge::Runtime::Instance::ModuleInstance::getFuncExports<WasmEdge_VMGetFunctionList::$_0>(WasmEdge_VMGetFunctionList::$_0&&) const
Unexecuted instantiation: vm.cpp:auto WasmEdge::Runtime::Instance::ModuleInstance::getFuncExports<WasmEdge::VM::VM::unsafeGetFunctionList() const::$_0>(WasmEdge::VM::VM::unsafeGetFunctionList() const::$_0&&) const
Unexecuted instantiation: component_alias.cpp:auto WasmEdge::Runtime::Instance::ModuleInstance::getFuncExports<WasmEdge::Executor::Executor::instantiate(WasmEdge::Runtime::Instance::ComponentInstance&, WasmEdge::AST::Component::AliasSection const&)::$_0&>(WasmEdge::Executor::Executor::instantiate(WasmEdge::Runtime::Instance::ComponentInstance&, WasmEdge::AST::Component::AliasSection const&)::$_0&) const
319
  template <typename CallbackT>
320
0
  auto getTableExports(CallbackT &&CallBack) const noexcept {
321
0
    std::shared_lock Lock(Mutex);
322
0
    return std::forward<CallbackT>(CallBack)(ExpTables);
323
0
  }
Unexecuted instantiation: wasmedge.cpp:auto WasmEdge::Runtime::Instance::ModuleInstance::getTableExports<WasmEdge_ModuleInstanceListTable::$_0>(WasmEdge_ModuleInstanceListTable::$_0&&) const
Unexecuted instantiation: component_alias.cpp:auto WasmEdge::Runtime::Instance::ModuleInstance::getTableExports<WasmEdge::Executor::Executor::instantiate(WasmEdge::Runtime::Instance::ComponentInstance&, WasmEdge::AST::Component::AliasSection const&)::$_0&>(WasmEdge::Executor::Executor::instantiate(WasmEdge::Runtime::Instance::ComponentInstance&, WasmEdge::AST::Component::AliasSection const&)::$_0&) const
324
  template <typename CallbackT>
325
0
  auto getMemoryExports(CallbackT &&CallBack) const noexcept {
326
0
    std::shared_lock Lock(Mutex);
327
0
    return std::forward<CallbackT>(CallBack)(ExpMems);
328
0
  }
Unexecuted instantiation: wasmedge.cpp:auto WasmEdge::Runtime::Instance::ModuleInstance::getMemoryExports<WasmEdge_ModuleInstanceListMemory::$_0>(WasmEdge_ModuleInstanceListMemory::$_0&&) const
Unexecuted instantiation: component_alias.cpp:auto WasmEdge::Runtime::Instance::ModuleInstance::getMemoryExports<WasmEdge::Executor::Executor::instantiate(WasmEdge::Runtime::Instance::ComponentInstance&, WasmEdge::AST::Component::AliasSection const&)::$_0&>(WasmEdge::Executor::Executor::instantiate(WasmEdge::Runtime::Instance::ComponentInstance&, WasmEdge::AST::Component::AliasSection const&)::$_0&) const
329
  template <typename CallbackT>
330
0
  auto getTagExports(CallbackT &&CallBack) const noexcept {
331
0
    std::shared_lock Lock(Mutex);
332
0
    return std::forward<CallbackT>(CallBack)(ExpTags);
333
0
  }
Unexecuted instantiation: wasmedge.cpp:auto WasmEdge::Runtime::Instance::ModuleInstance::getTagExports<WasmEdge_ModuleInstanceListTag::$_0>(WasmEdge_ModuleInstanceListTag::$_0&&) const
Unexecuted instantiation: component_alias.cpp:auto WasmEdge::Runtime::Instance::ModuleInstance::getTagExports<WasmEdge::Executor::Executor::instantiate(WasmEdge::Runtime::Instance::ComponentInstance&, WasmEdge::AST::Component::AliasSection const&)::$_0&>(WasmEdge::Executor::Executor::instantiate(WasmEdge::Runtime::Instance::ComponentInstance&, WasmEdge::AST::Component::AliasSection const&)::$_0&) const
334
  template <typename CallbackT>
335
0
  auto getGlobalExports(CallbackT &&CallBack) const noexcept {
336
0
    std::shared_lock Lock(Mutex);
337
0
    return std::forward<CallbackT>(CallBack)(ExpGlobals);
338
0
  }
Unexecuted instantiation: wasmedge.cpp:auto WasmEdge::Runtime::Instance::ModuleInstance::getGlobalExports<WasmEdge_ModuleInstanceListGlobal::$_0>(WasmEdge_ModuleInstanceListGlobal::$_0&&) const
Unexecuted instantiation: component_alias.cpp:auto WasmEdge::Runtime::Instance::ModuleInstance::getGlobalExports<WasmEdge::Executor::Executor::instantiate(WasmEdge::Runtime::Instance::ComponentInstance&, WasmEdge::AST::Component::AliasSection const&)::$_0&>(WasmEdge::Executor::Executor::instantiate(WasmEdge::Runtime::Instance::ComponentInstance&, WasmEdge::AST::Component::AliasSection const&)::$_0&) const
339
340
protected:
341
  friend class Executor::Executor;
342
  friend class ComponentInstance;
343
  friend class Runtime::CallingFrame;
344
345
  /// Create and copy the defined type to this module instance.
346
0
  void addDefinedType(const AST::SubType &SType) {
347
0
    std::unique_lock Lock(Mutex);
348
0
    OwnedTypes.push_back(std::make_unique<AST::SubType>(SType));
349
0
    Types.push_back(OwnedTypes.back().get());
350
0
  }
351
352
  /// Create and add instances to this module instance.
353
0
  template <typename... Args> void addFunc(Args &&...Values) {
354
0
    std::unique_lock Lock(Mutex);
355
0
    unsafeAddInstance(OwnedFuncInsts, FuncInsts, this,
356
0
                      std::forward<Args>(Values)...);
357
0
  }
Unexecuted instantiation: void WasmEdge::Runtime::Instance::ModuleInstance::addFunc<unsigned int const&, WasmEdge::AST::FunctionType const&, WasmEdge::Symbol<void> >(unsigned int const&, WasmEdge::AST::FunctionType const&, WasmEdge::Symbol<void>&&)
Unexecuted instantiation: void WasmEdge::Runtime::Instance::ModuleInstance::addFunc<unsigned int const&, WasmEdge::AST::FunctionType const&, cxx20::span<std::__1::pair<unsigned int, WasmEdge::ValType> const, 18446744073709551615ul>, cxx20::span<WasmEdge::AST::Instruction const, 18446744073709551615ul> >(unsigned int const&, WasmEdge::AST::FunctionType const&, cxx20::span<std::__1::pair<unsigned int, WasmEdge::ValType> const, 18446744073709551615ul>&&, cxx20::span<WasmEdge::AST::Instruction const, 18446744073709551615ul>&&)
358
0
  template <typename... Args> void addTable(Args &&...Values) {
359
0
    std::unique_lock Lock(Mutex);
360
0
    unsafeAddInstance(OwnedTabInsts, TabInsts, this,
361
0
                      std::forward<Args>(Values)...);
362
0
  }
363
0
  template <typename... Args> void addMemory(Args &&...Values) {
364
0
    std::unique_lock Lock(Mutex);
365
0
    unsafeAddInstance(OwnedMemInsts, MemInsts, std::forward<Args>(Values)...);
366
0
  }
367
0
  template <typename... Args> void addTag(Args &&...Values) {
368
0
    std::unique_lock Lock(Mutex);
369
0
    unsafeAddInstance(OwnedTagInsts, TagInsts, this,
370
0
                      std::forward<Args>(Values)...);
371
0
  }
372
0
  template <typename... Args> void addGlobal(Args &&...Values) {
373
0
    std::unique_lock Lock(Mutex);
374
0
    unsafeAddInstance(OwnedGlobInsts, GlobInsts, this,
375
0
                      std::forward<Args>(Values)...);
376
0
  }
377
0
  template <typename... Args> void addElem(Args &&...Values) {
378
0
    std::unique_lock Lock(Mutex);
379
0
    unsafeAddInstance(OwnedElemInsts, ElemInsts, std::forward<Args>(Values)...);
380
0
  }
381
0
  template <typename... Args> void addData(Args &&...Values) {
382
0
    std::unique_lock Lock(Mutex);
383
0
    unsafeAddInstance(OwnedDataInsts, DataInsts, std::forward<Args>(Values)...);
384
0
  }
385
0
  template <typename... Args> ArrayInstance *newArray(Args &&...Values) {
386
0
    std::unique_lock Lock(Mutex);
387
0
    OwnedArrayInsts.push_back(
388
0
        std::make_unique<ArrayInstance>(this, std::forward<Args>(Values)...));
389
0
    return OwnedArrayInsts.back().get();
390
0
  }
Unexecuted instantiation: WasmEdge::Runtime::Instance::ArrayInstance* WasmEdge::Runtime::Instance::ModuleInstance::newArray<unsigned int const&, unsigned int const&, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant>&>(unsigned int const&, unsigned int const&, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant>&)
Unexecuted instantiation: WasmEdge::Runtime::Instance::ArrayInstance* WasmEdge::Runtime::Instance::ModuleInstance::newArray<unsigned int const&, unsigned int const&, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant> >(unsigned int const&, unsigned int const&, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant>&&)
Unexecuted instantiation: WasmEdge::Runtime::Instance::ArrayInstance* WasmEdge::Runtime::Instance::ModuleInstance::newArray<unsigned int const&, std::__1::vector<WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant>, std::__1::allocator<WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant> > > >(unsigned int const&, std::__1::vector<WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant>, std::__1::allocator<WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant> > >&&)
391
0
  template <typename... Args> StructInstance *newStruct(Args &&...Values) {
392
0
    std::unique_lock Lock(Mutex);
393
0
    OwnedStructInsts.push_back(
394
0
        std::make_unique<StructInstance>(this, std::forward<Args>(Values)...));
395
0
    return OwnedStructInsts.back().get();
396
0
  }
397
  template <typename... Args>
398
0
  ExceptionInstance *newException(Args &&...Values) {
399
0
    std::unique_lock Lock(Mutex);
400
0
    OwnedExceptionInsts.push_back(
401
0
        std::make_unique<ExceptionInstance>(std::forward<Args>(Values)...));
402
0
    return OwnedExceptionInsts.back().get();
403
0
  }
Unexecuted instantiation: WasmEdge::Runtime::Instance::ExceptionInstance* WasmEdge::Runtime::Instance::ModuleInstance::newException<WasmEdge::Runtime::Instance::TagInstance*&, std::__1::vector<WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant>, std::__1::allocator<WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant> > > >(WasmEdge::Runtime::Instance::TagInstance*&, std::__1::vector<WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant>, std::__1::allocator<WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant> > >&&)
Unexecuted instantiation: WasmEdge::Runtime::Instance::ExceptionInstance* WasmEdge::Runtime::Instance::ModuleInstance::newException<WasmEdge::Runtime::Instance::TagInstance*, std::__1::vector<WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant>, std::__1::allocator<WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant> > > >(WasmEdge::Runtime::Instance::TagInstance*&&, std::__1::vector<WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant>, std::__1::allocator<WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant> > >&&)
404
405
  /// Import instances into this module instance.
406
0
  void importFunction(FunctionInstance *Func) {
407
0
    std::unique_lock Lock(Mutex);
408
0
    unsafeImportInstance(FuncInsts, Func);
409
0
  }
410
  /// Import a host function (FunctionInstance owned elsewhere). Registers
411
  /// the host function's defined type into this module's Types list so that
412
  /// downstream matchType() walks find it, and re-links the FunctionInstance
413
  /// to point at the new TypeIdx. Use this when a host function is bridged
414
  /// into a different module than the one that originally created it (e.g.,
415
  /// the inline-instance machinery in component instantiation).
416
0
  void importHostFunction(FunctionInstance *Func) {
417
0
    std::unique_lock Lock(Mutex);
418
0
    assuming(Func->isHostFunction());
419
0
    unsafeImportDefinedType(Func->getHostFunc().getDefinedType());
420
0
    Func->linkDefinedType(this, static_cast<uint32_t>(Types.size()) - 1);
421
0
    unsafeImportInstance(FuncInsts, Func);
422
0
  }
423
0
  void importTable(TableInstance *Tab) {
424
0
    std::unique_lock Lock(Mutex);
425
0
    unsafeImportInstance(TabInsts, Tab);
426
0
  }
427
0
  void importMemory(MemoryInstance *Mem) {
428
0
    std::unique_lock Lock(Mutex);
429
0
    unsafeImportInstance(MemInsts, Mem);
430
0
  }
431
0
  void importTag(TagInstance *Tg) {
432
0
    std::unique_lock Lock(Mutex);
433
0
    unsafeImportInstance(TagInsts, Tg);
434
0
  }
435
0
  void importGlobal(GlobalInstance *Glob) {
436
0
    std::unique_lock Lock(Mutex);
437
0
    ImpGlobalNum++;
438
0
    unsafeImportInstance(GlobInsts, Glob);
439
0
  }
440
441
  /// Export instances with name from this module instance.
442
0
  void exportFunction(std::string_view Name, uint32_t Idx) {
443
0
    std::unique_lock Lock(Mutex);
444
0
    ExpFuncs.insert_or_assign(std::string(Name), FuncInsts[Idx]);
445
0
  }
446
0
  void exportTable(std::string_view Name, uint32_t Idx) {
447
0
    std::unique_lock Lock(Mutex);
448
0
    ExpTables.insert_or_assign(std::string(Name), TabInsts[Idx]);
449
0
  }
450
0
  void exportMemory(std::string_view Name, uint32_t Idx) {
451
0
    std::unique_lock Lock(Mutex);
452
0
    ExpMems.insert_or_assign(std::string(Name), MemInsts[Idx]);
453
0
  }
454
0
  void exportGlobal(std::string_view Name, uint32_t Idx) {
455
0
    std::unique_lock Lock(Mutex);
456
0
    ExpGlobals.insert_or_assign(std::string(Name), GlobInsts[Idx]);
457
0
  }
458
0
  void exportTag(std::string_view Name, uint32_t Idx) {
459
0
    std::unique_lock Lock(Mutex);
460
0
    ExpTags.insert_or_assign(std::string(Name), TagInsts[Idx]);
461
0
  }
462
463
  /// Get instance pointer by index.
464
0
  const AST::SubType *unsafeGetType(uint32_t Idx) const noexcept {
465
0
    return Types[Idx];
466
0
  }
467
0
  Expect<FunctionInstance *> getFunc(uint32_t Idx) const noexcept {
468
0
    std::shared_lock Lock(Mutex);
469
0
    if (Idx >= FuncInsts.size()) {
470
0
      // Error logging needs to be handled by the caller.
471
0
      return Unexpect(ErrCode::Value::WrongInstanceIndex);
472
0
    }
473
0
    return unsafeGetFunction(Idx);
474
0
  }
475
0
  FunctionInstance *unsafeGetFunction(uint32_t Idx) const noexcept {
476
0
    return FuncInsts[Idx];
477
0
  }
478
0
  Expect<TableInstance *> getTable(uint32_t Idx) const noexcept {
479
0
    std::shared_lock Lock(Mutex);
480
0
    if (Idx >= TabInsts.size()) {
481
0
      // Error logging needs to be handled by the caller.
482
0
      return Unexpect(ErrCode::Value::WrongInstanceIndex);
483
0
    }
484
0
    return unsafeGetTable(Idx);
485
0
  }
486
0
  TableInstance *unsafeGetTable(uint32_t Idx) const noexcept {
487
0
    return TabInsts[Idx];
488
0
  }
489
0
  Expect<MemoryInstance *> getMemory(uint32_t Idx) const noexcept {
490
0
    std::shared_lock Lock(Mutex);
491
0
    if (Idx >= MemInsts.size()) {
492
      // Error logging needs to be handled by the caller.
493
0
      return Unexpect(ErrCode::Value::WrongInstanceIndex);
494
0
    }
495
0
    return unsafeGetMemory(Idx);
496
0
  }
497
0
  MemoryInstance *unsafeGetMemory(uint32_t Idx) const noexcept {
498
0
    return MemInsts[Idx];
499
0
  }
500
0
  TagInstance *unsafeGetTag(uint32_t Idx) const noexcept {
501
0
    return TagInsts[Idx];
502
0
  }
503
0
  Expect<GlobalInstance *> getGlobal(uint32_t Idx) const noexcept {
504
0
    std::shared_lock Lock(Mutex);
505
0
    if (Idx >= GlobInsts.size()) {
506
      // Error logging needs to be handled by the caller.
507
0
      return Unexpect(ErrCode::Value::WrongInstanceIndex);
508
0
    }
509
0
    return unsafeGetGlobal(Idx);
510
0
  }
511
0
  GlobalInstance *unsafeGetGlobal(uint32_t Idx) const noexcept {
512
0
    return GlobInsts[Idx];
513
0
  }
514
0
  Expect<ElementInstance *> getElem(uint32_t Idx) const noexcept {
515
0
    std::shared_lock Lock(Mutex);
516
0
    if (Idx >= ElemInsts.size()) {
517
0
      // Error logging needs to be handled by the caller.
518
0
      return Unexpect(ErrCode::Value::WrongInstanceIndex);
519
0
    }
520
0
    return unsafeGetElem(Idx);
521
0
  }
522
0
  ElementInstance *unsafeGetElem(uint32_t Idx) const noexcept {
523
0
    return ElemInsts[Idx];
524
0
  }
525
0
  Expect<DataInstance *> getData(uint32_t Idx) const noexcept {
526
0
    std::shared_lock Lock(Mutex);
527
0
    if (Idx >= DataInsts.size()) {
528
0
      // Error logging needs to be handled by the caller.
529
0
      return Unexpect(ErrCode::Value::WrongInstanceIndex);
530
0
    }
531
0
    return unsafeGetData(Idx);
532
0
  }
533
0
  DataInstance *unsafeGetData(uint32_t Idx) const noexcept {
534
0
    return DataInsts[Idx];
535
0
  }
536
537
  /// Get the instances count.
538
0
  uint32_t getFuncNum() const noexcept {
539
0
    std::shared_lock Lock(Mutex);
540
0
    return static_cast<uint32_t>(FuncInsts.size());
541
0
  }
542
0
  uint32_t getTableNum() const noexcept {
543
0
    std::shared_lock Lock(Mutex);
544
0
    return static_cast<uint32_t>(TabInsts.size());
545
0
  }
546
0
  uint32_t getMemoryNum() const noexcept {
547
0
    std::shared_lock Lock(Mutex);
548
0
    return static_cast<uint32_t>(MemInsts.size());
549
0
  }
550
0
  uint32_t getGlobalNum() const noexcept {
551
0
    std::shared_lock Lock(Mutex);
552
0
    return static_cast<uint32_t>(GlobInsts.size());
553
0
  }
554
555
  /// Get imported global instances count.
556
0
  uint32_t getGlobalImportNum() const noexcept { return ImpGlobalNum; }
557
558
  /// Set the start function index and find the function instance.
559
0
  void setStartIdx(uint32_t Idx) noexcept {
560
0
    std::unique_lock Lock(Mutex);
561
0
    StartFunc = FuncInsts[Idx];
562
0
  }
563
564
  /// Get start function address in Store.
565
0
  const FunctionInstance *getStartFunc() const noexcept {
566
0
    std::shared_lock Lock(Mutex);
567
0
    return StartFunc;
568
0
  }
569
570
  /// Set the target imported WASI module during instantiation.
571
0
  void setWASIModule(const ModuleInstance *Mod) noexcept {
572
0
    std::unique_lock Lock(Mutex);
573
0
    WASIModInst = Mod;
574
0
  }
575
576
  /// Get the target imported WASI module during instantiation.
577
0
  const ModuleInstance *getWASIModule() const noexcept {
578
0
    std::shared_lock Lock(Mutex);
579
0
    return WASIModInst;
580
0
  }
581
582
  /// Unsafely import an instance into this module. Only valid before
583
  /// finalization: buildContext() caches the instance vectors' buffers, which a
584
  /// later push_back may reallocate.
585
  template <typename T>
586
  std::enable_if_t<IsEntityV<T>, void>
587
0
  unsafeImportInstance(std::vector<T *> &Vec, T *Ptr) {
588
0
    assuming(!isInstantiateFinalized());
589
0
    Vec.push_back(Ptr);
590
0
  }
Unexecuted instantiation: std::__1::enable_if<IsEntityV<WasmEdge::Runtime::Instance::FunctionInstance>, void>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeImportInstance<WasmEdge::Runtime::Instance::FunctionInstance>(std::__1::vector<WasmEdge::Runtime::Instance::FunctionInstance*, std::__1::allocator<WasmEdge::Runtime::Instance::FunctionInstance*> >&, WasmEdge::Runtime::Instance::FunctionInstance*)
Unexecuted instantiation: std::__1::enable_if<IsEntityV<WasmEdge::Runtime::Instance::GlobalInstance>, void>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeImportInstance<WasmEdge::Runtime::Instance::GlobalInstance>(std::__1::vector<WasmEdge::Runtime::Instance::GlobalInstance*, std::__1::allocator<WasmEdge::Runtime::Instance::GlobalInstance*> >&, WasmEdge::Runtime::Instance::GlobalInstance*)
Unexecuted instantiation: std::__1::enable_if<IsEntityV<WasmEdge::Runtime::Instance::TableInstance>, void>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeImportInstance<WasmEdge::Runtime::Instance::TableInstance>(std::__1::vector<WasmEdge::Runtime::Instance::TableInstance*, std::__1::allocator<WasmEdge::Runtime::Instance::TableInstance*> >&, WasmEdge::Runtime::Instance::TableInstance*)
Unexecuted instantiation: std::__1::enable_if<IsEntityV<WasmEdge::Runtime::Instance::MemoryInstance>, void>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeImportInstance<WasmEdge::Runtime::Instance::MemoryInstance>(std::__1::vector<WasmEdge::Runtime::Instance::MemoryInstance*, std::__1::allocator<WasmEdge::Runtime::Instance::MemoryInstance*> >&, WasmEdge::Runtime::Instance::MemoryInstance*)
Unexecuted instantiation: std::__1::enable_if<IsEntityV<WasmEdge::Runtime::Instance::TagInstance>, void>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeImportInstance<WasmEdge::Runtime::Instance::TagInstance>(std::__1::vector<WasmEdge::Runtime::Instance::TagInstance*, std::__1::allocator<WasmEdge::Runtime::Instance::TagInstance*> >&, WasmEdge::Runtime::Instance::TagInstance*)
591
592
  /// Unsafely import a defined type from a host function into this module.
593
0
  void unsafeImportDefinedType(const AST::SubType &SType) {
594
0
    Types.push_back(&SType);
595
0
    const_cast<AST::SubType *>(Types.back())
596
0
        ->setTypeIndex(static_cast<uint32_t>(Types.size()) - 1);
597
0
  }
598
599
  /// Unsafely create and add the instance to this module. Only valid before
600
  /// finalization: buildContext() caches the instance vectors' buffers, which a
601
  /// later push_back may reallocate.
602
  template <typename T, typename... Args>
603
  std::enable_if_t<IsInstanceV<T>, void>
604
  unsafeAddInstance(std::vector<std::unique_ptr<T>> &OwnedInstsVec,
605
0
                    std::vector<T *> &InstsVec, Args &&...Values) {
606
0
    assuming(!isInstantiateFinalized());
607
0
    OwnedInstsVec.push_back(std::make_unique<T>(std::forward<Args>(Values)...));
608
0
    InstsVec.push_back(OwnedInstsVec.back().get());
609
0
  }
Unexecuted instantiation: std::__1::enable_if<IsInstanceV<WasmEdge::Runtime::Instance::FunctionInstance>, void>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeAddInstance<WasmEdge::Runtime::Instance::FunctionInstance, WasmEdge::Runtime::Instance::ModuleInstance*, unsigned int const&, WasmEdge::AST::FunctionType const&, WasmEdge::Symbol<void> >(std::__1::vector<std::__1::unique_ptr<WasmEdge::Runtime::Instance::FunctionInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::FunctionInstance> >, std::__1::allocator<std::__1::unique_ptr<WasmEdge::Runtime::Instance::FunctionInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::FunctionInstance> > > >&, std::__1::vector<WasmEdge::Runtime::Instance::FunctionInstance*, std::__1::allocator<WasmEdge::Runtime::Instance::FunctionInstance*> >&, WasmEdge::Runtime::Instance::ModuleInstance*&&, unsigned int const&, WasmEdge::AST::FunctionType const&, WasmEdge::Symbol<void>&&)
Unexecuted instantiation: std::__1::enable_if<IsInstanceV<WasmEdge::Runtime::Instance::FunctionInstance>, void>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeAddInstance<WasmEdge::Runtime::Instance::FunctionInstance, WasmEdge::Runtime::Instance::ModuleInstance*, unsigned int const&, WasmEdge::AST::FunctionType const&, cxx20::span<std::__1::pair<unsigned int, WasmEdge::ValType> const, 18446744073709551615ul>, cxx20::span<WasmEdge::AST::Instruction const, 18446744073709551615ul> >(std::__1::vector<std::__1::unique_ptr<WasmEdge::Runtime::Instance::FunctionInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::FunctionInstance> >, std::__1::allocator<std::__1::unique_ptr<WasmEdge::Runtime::Instance::FunctionInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::FunctionInstance> > > >&, std::__1::vector<WasmEdge::Runtime::Instance::FunctionInstance*, std::__1::allocator<WasmEdge::Runtime::Instance::FunctionInstance*> >&, WasmEdge::Runtime::Instance::ModuleInstance*&&, unsigned int const&, WasmEdge::AST::FunctionType const&, cxx20::span<std::__1::pair<unsigned int, WasmEdge::ValType> const, 18446744073709551615ul>&&, cxx20::span<WasmEdge::AST::Instruction const, 18446744073709551615ul>&&)
Unexecuted instantiation: std::__1::enable_if<IsInstanceV<WasmEdge::Runtime::Instance::GlobalInstance>, void>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeAddInstance<WasmEdge::Runtime::Instance::GlobalInstance, WasmEdge::Runtime::Instance::ModuleInstance*, WasmEdge::AST::GlobalType const&, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant>&>(std::__1::vector<std::__1::unique_ptr<WasmEdge::Runtime::Instance::GlobalInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::GlobalInstance> >, std::__1::allocator<std::__1::unique_ptr<WasmEdge::Runtime::Instance::GlobalInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::GlobalInstance> > > >&, std::__1::vector<WasmEdge::Runtime::Instance::GlobalInstance*, std::__1::allocator<WasmEdge::Runtime::Instance::GlobalInstance*> >&, WasmEdge::Runtime::Instance::ModuleInstance*&&, WasmEdge::AST::GlobalType const&, WasmEdge::Variant<unsigned int, int, unsigned long, long, float, double, unsigned __int128, __int128, cxx26::simd::basic_vec<unsigned long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> >, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> >, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> >, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> >, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> >, WasmEdge::RefVariant>&)
Unexecuted instantiation: std::__1::enable_if<IsInstanceV<WasmEdge::Runtime::Instance::TableInstance>, void>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeAddInstance<WasmEdge::Runtime::Instance::TableInstance, WasmEdge::Runtime::Instance::ModuleInstance*, WasmEdge::AST::TableType const&, WasmEdge::RefVariant&>(std::__1::vector<std::__1::unique_ptr<WasmEdge::Runtime::Instance::TableInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::TableInstance> >, std::__1::allocator<std::__1::unique_ptr<WasmEdge::Runtime::Instance::TableInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::TableInstance> > > >&, std::__1::vector<WasmEdge::Runtime::Instance::TableInstance*, std::__1::allocator<WasmEdge::Runtime::Instance::TableInstance*> >&, WasmEdge::Runtime::Instance::ModuleInstance*&&, WasmEdge::AST::TableType const&, WasmEdge::RefVariant&)
Unexecuted instantiation: std::__1::enable_if<IsInstanceV<WasmEdge::Runtime::Instance::MemoryInstance>, void>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeAddInstance<WasmEdge::Runtime::Instance::MemoryInstance, WasmEdge::AST::MemoryType const&, unsigned long>(std::__1::vector<std::__1::unique_ptr<WasmEdge::Runtime::Instance::MemoryInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::MemoryInstance> >, std::__1::allocator<std::__1::unique_ptr<WasmEdge::Runtime::Instance::MemoryInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::MemoryInstance> > > >&, std::__1::vector<WasmEdge::Runtime::Instance::MemoryInstance*, std::__1::allocator<WasmEdge::Runtime::Instance::MemoryInstance*> >&, WasmEdge::AST::MemoryType const&, unsigned long&&)
Unexecuted instantiation: std::__1::enable_if<IsInstanceV<WasmEdge::Runtime::Instance::ElementInstance>, void>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeAddInstance<WasmEdge::Runtime::Instance::ElementInstance, unsigned long&, WasmEdge::ValType const&, std::__1::vector<WasmEdge::RefVariant, std::__1::allocator<WasmEdge::RefVariant> >&>(std::__1::vector<std::__1::unique_ptr<WasmEdge::Runtime::Instance::ElementInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::ElementInstance> >, std::__1::allocator<std::__1::unique_ptr<WasmEdge::Runtime::Instance::ElementInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::ElementInstance> > > >&, std::__1::vector<WasmEdge::Runtime::Instance::ElementInstance*, std::__1::allocator<WasmEdge::Runtime::Instance::ElementInstance*> >&, unsigned long&, WasmEdge::ValType const&, std::__1::vector<WasmEdge::RefVariant, std::__1::allocator<WasmEdge::RefVariant> >&)
Unexecuted instantiation: std::__1::enable_if<IsInstanceV<WasmEdge::Runtime::Instance::DataInstance>, void>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeAddInstance<WasmEdge::Runtime::Instance::DataInstance, unsigned long&, cxx20::span<unsigned char const, 18446744073709551615ul> >(std::__1::vector<std::__1::unique_ptr<WasmEdge::Runtime::Instance::DataInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::DataInstance> >, std::__1::allocator<std::__1::unique_ptr<WasmEdge::Runtime::Instance::DataInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::DataInstance> > > >&, std::__1::vector<WasmEdge::Runtime::Instance::DataInstance*, std::__1::allocator<WasmEdge::Runtime::Instance::DataInstance*> >&, unsigned long&, cxx20::span<unsigned char const, 18446744073709551615ul>&&)
Unexecuted instantiation: std::__1::enable_if<IsInstanceV<WasmEdge::Runtime::Instance::TagInstance>, void>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeAddInstance<WasmEdge::Runtime::Instance::TagInstance, WasmEdge::Runtime::Instance::ModuleInstance*, WasmEdge::AST::TagType const&, WasmEdge::AST::SubType const*&>(std::__1::vector<std::__1::unique_ptr<WasmEdge::Runtime::Instance::TagInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::TagInstance> >, std::__1::allocator<std::__1::unique_ptr<WasmEdge::Runtime::Instance::TagInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::TagInstance> > > >&, std::__1::vector<WasmEdge::Runtime::Instance::TagInstance*, std::__1::allocator<WasmEdge::Runtime::Instance::TagInstance*> >&, WasmEdge::Runtime::Instance::ModuleInstance*&&, WasmEdge::AST::TagType const&, WasmEdge::AST::SubType const*&)
610
611
  /// Unsafely add and export the existing instance to this module.
612
  template <typename T, typename... Args>
613
  std::enable_if_t<IsEntityV<T>, void>
614
  unsafeAddHostInstance(std::string_view Name,
615
                        std::vector<std::unique_ptr<T>> &OwnedInstsVec,
616
                        std::vector<T *> &InstsVec,
617
                        std::map<std::string, T *, std::less<>> &InstsMap,
618
0
                        std::unique_ptr<T> &&Inst) {
619
0
    OwnedInstsVec.push_back(std::move(Inst));
620
0
    InstsVec.push_back(OwnedInstsVec.back().get());
621
0
    InstsMap.insert_or_assign(std::string(Name), InstsVec.back());
622
0
  }
Unexecuted instantiation: std::__1::enable_if<IsEntityV<WasmEdge::Runtime::Instance::FunctionInstance>, void>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeAddHostInstance<WasmEdge::Runtime::Instance::FunctionInstance>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, std::__1::vector<std::__1::unique_ptr<WasmEdge::Runtime::Instance::FunctionInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::FunctionInstance> >, std::__1::allocator<std::__1::unique_ptr<WasmEdge::Runtime::Instance::FunctionInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::FunctionInstance> > > >&, std::__1::vector<WasmEdge::Runtime::Instance::FunctionInstance*, std::__1::allocator<WasmEdge::Runtime::Instance::FunctionInstance*> >&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, WasmEdge::Runtime::Instance::FunctionInstance*, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, WasmEdge::Runtime::Instance::FunctionInstance*> > >&, std::__1::unique_ptr<WasmEdge::Runtime::Instance::FunctionInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::FunctionInstance> >&&)
Unexecuted instantiation: std::__1::enable_if<IsEntityV<WasmEdge::Runtime::Instance::TableInstance>, void>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeAddHostInstance<WasmEdge::Runtime::Instance::TableInstance>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, std::__1::vector<std::__1::unique_ptr<WasmEdge::Runtime::Instance::TableInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::TableInstance> >, std::__1::allocator<std::__1::unique_ptr<WasmEdge::Runtime::Instance::TableInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::TableInstance> > > >&, std::__1::vector<WasmEdge::Runtime::Instance::TableInstance*, std::__1::allocator<WasmEdge::Runtime::Instance::TableInstance*> >&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, WasmEdge::Runtime::Instance::TableInstance*, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, WasmEdge::Runtime::Instance::TableInstance*> > >&, std::__1::unique_ptr<WasmEdge::Runtime::Instance::TableInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::TableInstance> >&&)
Unexecuted instantiation: std::__1::enable_if<IsEntityV<WasmEdge::Runtime::Instance::MemoryInstance>, void>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeAddHostInstance<WasmEdge::Runtime::Instance::MemoryInstance>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, std::__1::vector<std::__1::unique_ptr<WasmEdge::Runtime::Instance::MemoryInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::MemoryInstance> >, std::__1::allocator<std::__1::unique_ptr<WasmEdge::Runtime::Instance::MemoryInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::MemoryInstance> > > >&, std::__1::vector<WasmEdge::Runtime::Instance::MemoryInstance*, std::__1::allocator<WasmEdge::Runtime::Instance::MemoryInstance*> >&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, WasmEdge::Runtime::Instance::MemoryInstance*, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, WasmEdge::Runtime::Instance::MemoryInstance*> > >&, std::__1::unique_ptr<WasmEdge::Runtime::Instance::MemoryInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::MemoryInstance> >&&)
Unexecuted instantiation: std::__1::enable_if<IsEntityV<WasmEdge::Runtime::Instance::GlobalInstance>, void>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeAddHostInstance<WasmEdge::Runtime::Instance::GlobalInstance>(std::__1::basic_string_view<char, std::__1::char_traits<char> >, std::__1::vector<std::__1::unique_ptr<WasmEdge::Runtime::Instance::GlobalInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::GlobalInstance> >, std::__1::allocator<std::__1::unique_ptr<WasmEdge::Runtime::Instance::GlobalInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::GlobalInstance> > > >&, std::__1::vector<WasmEdge::Runtime::Instance::GlobalInstance*, std::__1::allocator<WasmEdge::Runtime::Instance::GlobalInstance*> >&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, WasmEdge::Runtime::Instance::GlobalInstance*, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, WasmEdge::Runtime::Instance::GlobalInstance*> > >&, std::__1::unique_ptr<WasmEdge::Runtime::Instance::GlobalInstance, std::__1::default_delete<WasmEdge::Runtime::Instance::GlobalInstance> >&&)
623
624
  /// Unsafely find and get the exported instance by name.
625
  template <typename T>
626
  std::enable_if_t<IsEntityV<T>, T *>
627
  unsafeFindExports(const std::map<std::string, T *, std::less<>> &Map,
628
0
                    std::string_view ExtName) const noexcept {
629
0
    auto Iter = Map.find(ExtName);
630
0
    if (likely(Iter != Map.cend())) {
631
0
      return Iter->second;
632
0
    }
633
0
    return nullptr;
634
0
  }
Unexecuted instantiation: std::__1::enable_if<IsEntityV<WasmEdge::Runtime::Instance::FunctionInstance>, WasmEdge::Runtime::Instance::FunctionInstance*>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeFindExports<WasmEdge::Runtime::Instance::FunctionInstance>(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, WasmEdge::Runtime::Instance::FunctionInstance*, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, WasmEdge::Runtime::Instance::FunctionInstance*> > > const&, std::__1::basic_string_view<char, std::__1::char_traits<char> >) const
Unexecuted instantiation: std::__1::enable_if<IsEntityV<WasmEdge::Runtime::Instance::GlobalInstance>, WasmEdge::Runtime::Instance::GlobalInstance*>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeFindExports<WasmEdge::Runtime::Instance::GlobalInstance>(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, WasmEdge::Runtime::Instance::GlobalInstance*, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, WasmEdge::Runtime::Instance::GlobalInstance*> > > const&, std::__1::basic_string_view<char, std::__1::char_traits<char> >) const
Unexecuted instantiation: std::__1::enable_if<IsEntityV<WasmEdge::Runtime::Instance::TableInstance>, WasmEdge::Runtime::Instance::TableInstance*>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeFindExports<WasmEdge::Runtime::Instance::TableInstance>(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, WasmEdge::Runtime::Instance::TableInstance*, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, WasmEdge::Runtime::Instance::TableInstance*> > > const&, std::__1::basic_string_view<char, std::__1::char_traits<char> >) const
Unexecuted instantiation: std::__1::enable_if<IsEntityV<WasmEdge::Runtime::Instance::MemoryInstance>, WasmEdge::Runtime::Instance::MemoryInstance*>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeFindExports<WasmEdge::Runtime::Instance::MemoryInstance>(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, WasmEdge::Runtime::Instance::MemoryInstance*, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, WasmEdge::Runtime::Instance::MemoryInstance*> > > const&, std::__1::basic_string_view<char, std::__1::char_traits<char> >) const
Unexecuted instantiation: std::__1::enable_if<IsEntityV<WasmEdge::Runtime::Instance::TagInstance>, WasmEdge::Runtime::Instance::TagInstance*>::type WasmEdge::Runtime::Instance::ModuleInstance::unsafeFindExports<WasmEdge::Runtime::Instance::TagInstance>(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, WasmEdge::Runtime::Instance::TagInstance*, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, WasmEdge::Runtime::Instance::TagInstance*> > > const&, std::__1::basic_string_view<char, std::__1::char_traits<char> >) const
635
636
  /// \name Data for compiled functions.
637
  /// @{
638
#if WASMEDGE_ALLOCATOR_IS_STABLE
639
  std::vector<uint8_t *> MemoryPtrs;
640
#else
641
  std::vector<uint8_t **> MemoryPtrs;
642
#endif
643
  std::vector<const uint64_t *> MemorySizePtrs;
644
  std::vector<const uint64_t *> TableSizePtrs;
645
  std::vector<RefVariant **> TableRefPtrs;
646
  std::vector<ValVariant *> GlobalPtrs;
647
  /// @}
648
649
  struct ModuleContext {
650
#if WASMEDGE_ALLOCATOR_IS_STABLE
651
    uint8_t *const *Memories;
652
#else
653
    uint8_t **const *Memories;
654
#endif
655
    const uint64_t *const *MemorySizes;
656
    RefVariant **const *TableRefs;
657
    const uint64_t *const *TableSizes;
658
    ValVariant *const *Globals;
659
    const void *ModuleInst;
660
    void *const *Tags;
661
  };
662
663
  /// Compiled code reads this struct by field index through the mirrored ModCtx
664
  /// type built in lib/llvm/compiler/context.cpp. Keep both in the same order.
665
  static_assert(sizeof(ModuleContext) == 7 * sizeof(void *));
666
  static_assert(offsetof(ModuleContext, Memories) == 0 * sizeof(void *));
667
  static_assert(offsetof(ModuleContext, MemorySizes) == 1 * sizeof(void *));
668
  static_assert(offsetof(ModuleContext, TableRefs) == 2 * sizeof(void *));
669
  static_assert(offsetof(ModuleContext, TableSizes) == 3 * sizeof(void *));
670
  static_assert(offsetof(ModuleContext, Globals) == 4 * sizeof(void *));
671
  static_assert(offsetof(ModuleContext, ModuleInst) == 5 * sizeof(void *));
672
  static_assert(offsetof(ModuleContext, Tags) == 6 * sizeof(void *));
673
674
  ModuleContext ModCtx{};
675
676
  /// Snapshot the instance vectors' buffers for compiled code. Call once, after
677
  /// the last instance is added and before the start function runs; adding an
678
  /// instance afterwards may reallocate and leave the context dangling.
679
0
  void buildContext() noexcept {
680
0
    ModCtx.Memories = MemoryPtrs.data();
681
0
    ModCtx.MemorySizes = MemorySizePtrs.data();
682
0
    ModCtx.TableRefs = TableRefPtrs.data();
683
0
    ModCtx.TableSizes = TableSizePtrs.data();
684
0
    ModCtx.Globals = GlobalPtrs.data();
685
0
    ModCtx.ModuleInst = this;
686
0
    ModCtx.Tags = reinterpret_cast<void *const *>(TagInsts.data());
687
0
  }
688
689
  friend class Runtime::StoreManager;
690
  using LinkedStoreKey = std::pair<StoreManager *, std::string>;
691
  using BeforeModuleDestroyCallback = void(const LinkedStoreKey &Key,
692
                                           const ModuleInstance *Mod);
693
  void linkStore(StoreManager *Store, std::string_view Name,
694
0
                 BeforeModuleDestroyCallback Callback) {
695
    // Link to the store during registration.
696
0
    std::unique_lock Lock(Mutex);
697
0
    LinkedStore.insert_or_assign(LinkedStoreKey{Store, std::string(Name)},
698
0
                                 Callback);
699
0
  }
700
701
0
  void unlinkStore(StoreManager *Store, std::string_view Name) {
702
    // Unlink a specific (Store, Name) entry.
703
0
    std::unique_lock Lock(Mutex);
704
0
    LinkedStore.erase(LinkedStoreKey{Store, std::string(Name)});
705
0
  }
706
707
0
  void unlinkAllStores() noexcept {
708
0
    std::map<LinkedStoreKey, std::function<BeforeModuleDestroyCallback>>
709
0
        Snapshot;
710
0
    {
711
0
      std::unique_lock Lock(Mutex);
712
0
      Snapshot.swap(LinkedStore);
713
0
    }
714
0
    for (auto &&[Key, Callback] : Snapshot) {
715
0
      assuming(Callback);
716
0
      Callback(Key, this);
717
0
    }
718
0
  }
719
720
0
  void addDependency(ModuleInstance &Provider) {
721
0
    std::unique_lock Lock(Mutex);
722
0
    if (Providers.insert(&Provider).second) {
723
0
      Provider.Life.addDependent();
724
0
    }
725
0
  }
726
727
0
  void takeProviders(std::unordered_set<ModuleInstance *> &Snapshot) noexcept {
728
0
    std::unique_lock Lock(Mutex);
729
0
    Snapshot.swap(Providers);
730
0
  }
731
732
  static void drainPins(std::unordered_set<ModuleInstance *> &Provs,
733
0
                        std::vector<ModuleInstance *> &ToDelete) noexcept {
734
0
    for (auto *Provider : Provs) {
735
0
      if (Provider->Life.releaseDependent()) {
736
0
        ToDelete.push_back(Provider);
737
0
      }
738
0
    }
739
0
    Provs.clear();
740
0
  }
741
742
0
  void releaseProviders() noexcept {
743
0
    std::unordered_set<ModuleInstance *> ProvidersToRelease;
744
0
    takeProviders(ProvidersToRelease);
745
0
    if (ProvidersToRelease.empty()) {
746
0
      return;
747
0
    }
748
0
    std::vector<ModuleInstance *> ToDelete;
749
0
    drainPins(ProvidersToRelease, ToDelete);
750
0
    while (!ToDelete.empty()) {
751
0
      ModuleInstance *Next = ToDelete.back();
752
0
      ToDelete.pop_back();
753
0
      std::unordered_set<ModuleInstance *> NextProviders;
754
0
      Next->takeProviders(NextProviders);
755
0
      delete Next;
756
0
      drainPins(NextProviders, ToDelete);
757
0
    }
758
0
  }
759
760
  /// Mutex.
761
  mutable std::shared_mutex Mutex;
762
763
  /// Module name.
764
  const std::string ModName;
765
766
  /// Defined types.
767
  std::vector<const AST::SubType *> Types;
768
  std::vector<std::unique_ptr<const AST::SubType>> OwnedTypes;
769
770
  /// Owned instances in this module.
771
  std::vector<std::unique_ptr<FunctionInstance>> OwnedFuncInsts;
772
  std::vector<std::unique_ptr<TableInstance>> OwnedTabInsts;
773
  std::vector<std::unique_ptr<MemoryInstance>> OwnedMemInsts;
774
  std::vector<std::unique_ptr<TagInstance>> OwnedTagInsts;
775
  std::vector<std::unique_ptr<GlobalInstance>> OwnedGlobInsts;
776
  std::vector<std::unique_ptr<ElementInstance>> OwnedElemInsts;
777
  std::vector<std::unique_ptr<DataInstance>> OwnedDataInsts;
778
  std::vector<std::unique_ptr<ArrayInstance>> OwnedArrayInsts;
779
  std::vector<std::unique_ptr<StructInstance>> OwnedStructInsts;
780
  std::vector<std::unique_ptr<ExceptionInstance>> OwnedExceptionInsts;
781
782
  /// Imported and added instances in this module.
783
  std::vector<FunctionInstance *> FuncInsts;
784
  std::vector<TableInstance *> TabInsts;
785
  std::vector<MemoryInstance *> MemInsts;
786
  std::vector<TagInstance *> TagInsts;
787
  std::vector<GlobalInstance *> GlobInsts;
788
  std::vector<ElementInstance *> ElemInsts;
789
  std::vector<DataInstance *> DataInsts;
790
791
  /// Imported instance counts.
792
  uint32_t ImpGlobalNum = 0;
793
794
  /// Exported name maps.
795
  std::map<std::string, FunctionInstance *, std::less<>> ExpFuncs;
796
  std::map<std::string, TableInstance *, std::less<>> ExpTables;
797
  std::map<std::string, MemoryInstance *, std::less<>> ExpMems;
798
  std::map<std::string, TagInstance *, std::less<>> ExpTags;
799
  std::map<std::string, GlobalInstance *, std::less<>> ExpGlobals;
800
801
  /// Start function instance.
802
  const FunctionInstance *StartFunc = nullptr;
803
804
  /// Imported WASI module instance during instantiation.
805
  const ModuleInstance *WASIModInst = nullptr;
806
807
  /// Linked store. Key is (StoreManager*, RegisteredName) to support
808
  /// the same module registered under multiple alias names.
809
  std::map<LinkedStoreKey, std::function<BeforeModuleDestroyCallback>>
810
      LinkedStore;
811
812
  /// External data and its finalizer function pointer.
813
  void *HostData;
814
  std::function<void(void *)> HostDataFinalizer;
815
816
  /// Whether this module instance has been finalized (immutable). Once set,
817
  /// the indexed instances will not be mutated anymore.
818
  mutable std::atomic<bool> InstantiateFinalized{false};
819
820
  /// Intrusive lifetime: owner flag plus importer count, packed into one
821
  /// atomic.
822
  RefLifetime Life;
823
  /// Provider instances this module imported from; each holds one dependent
824
  /// pin, released when this module is destroyed.
825
  std::unordered_set<ModuleInstance *> Providers;
826
};
827
828
} // namespace Instance
829
} // namespace Runtime
830
} // namespace WasmEdge