Coverage Report

Created: 2026-06-30 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/lib/executor/instantiate/module.cpp
Line
Count
Source
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright The WasmEdge Authors
3
4
#include "executor/executor.h"
5
6
#include "common/errinfo.h"
7
#include "common/spdlog.h"
8
9
#include <cstdint>
10
#include <string_view>
11
12
namespace WasmEdge {
13
namespace Executor {
14
15
// Instantiate module instance. See "include/executor/Executor.h".
16
Expect<std::unique_ptr<Runtime::Instance::ModuleInstance>>
17
Executor::instantiate(Runtime::StoreManager &StoreMgr, const AST::Module &Mod,
18
0
                      std::optional<std::string_view> Name) {
19
  // Check that the module is validated.
20
0
  if (unlikely(!Mod.getIsValidated())) {
21
0
    spdlog::error(ErrCode::Value::NotValidated);
22
0
    spdlog::error(ErrInfo::InfoAST(ASTNodeAttr::Module));
23
0
    return Unexpect(ErrCode::Value::NotValidated);
24
0
  }
25
26
  // Create the stack manager.
27
0
  Runtime::StackManager StackMgr;
28
29
  // Check whether the module name is duplicated during registration.
30
0
  if (Name.has_value()) {
31
0
    const auto *FindModInst = StoreMgr.findModule(Name.value());
32
0
    if (FindModInst != nullptr) {
33
0
      spdlog::error(ErrCode::Value::ModuleNameConflict);
34
0
      spdlog::error(ErrInfo::InfoAST(ASTNodeAttr::Module));
35
0
      return Unexpect(ErrCode::Value::ModuleNameConflict);
36
0
    }
37
0
  }
38
39
  // Insert the module instance into the store manager and retrieve it.
40
0
  std::unique_ptr<Runtime::Instance::ModuleInstance> ModInst;
41
0
  if (Name.has_value()) {
42
0
    ModInst = std::make_unique<Runtime::Instance::ModuleInstance>(Name.value());
43
0
  } else {
44
0
    ModInst = std::make_unique<Runtime::Instance::ModuleInstance>("");
45
0
  }
46
47
  // Instantiate Function Types in Module Instance. (TypeSec)
48
0
  for (auto &SubType : Mod.getTypeSection().getContent()) {
49
    // Copy defined types to module instance.
50
0
    ModInst->addDefinedType(SubType);
51
0
  }
52
53
0
  auto ReportModuleError = [&StoreMgr, &ModInst](auto E) {
54
0
    spdlog::error(ErrInfo::InfoAST(ASTNodeAttr::Module));
55
0
    StoreMgr.recycleModule(std::move(ModInst));
56
0
    return E;
57
0
  };
58
59
0
  auto ReportError = [&StoreMgr, &ModInst](ASTNodeAttr Attr) {
60
0
    return [Attr, &StoreMgr, &ModInst](auto E) {
61
0
      spdlog::error(ErrInfo::InfoAST(Attr));
62
0
      spdlog::error(ErrInfo::InfoAST(ASTNodeAttr::Module));
63
0
      StoreMgr.recycleModule(std::move(ModInst));
64
0
      return E;
65
0
    };
66
0
  };
67
68
  // Instantiate ImportSection and do import matching. (ImportSec)
69
0
  const AST::ImportSection &ImportSec = Mod.getImportSection();
70
0
  EXPECTED_TRY(instantiate(
71
0
                   [&StoreMgr, &ModInst](std::string_view ModName)
72
0
                       -> const WasmEdge::Runtime::Instance::ModuleInstance * {
73
0
                     using WasmEdge::Runtime::Instance::ModuleInstance;
74
0
                     return StoreMgr.withModuleLocked(
75
0
                         ModName,
76
0
                         [&ModInst](const ModuleInstance *Found)
77
0
                             -> const ModuleInstance * {
78
0
                           if (Found) {
79
0
                             ModInst->addDependency(
80
0
                                 *const_cast<ModuleInstance *>(Found));
81
0
                           }
82
0
                           return Found;
83
0
                         });
84
0
                   },
85
0
                   *ModInst, ImportSec)
86
0
                   .map_error(ReportError(ASTNodeAttr::Sec_Import)));
87
88
  // Instantiate Functions in module. (FunctionSec, CodeSec)
89
0
  const AST::FunctionSection &FuncSec = Mod.getFunctionSection();
90
0
  const AST::CodeSection &CodeSec = Mod.getCodeSection();
91
  // This function will always success.
92
0
  instantiate(*ModInst, FuncSec, CodeSec);
93
94
  // Instantiate MemorySection (MemorySec)
95
0
  const AST::MemorySection &MemSec = Mod.getMemorySection();
96
  // This function will always success.
97
0
  instantiate(*ModInst, MemSec);
98
99
  // Instantiate TagSection (TagSec)
100
0
  const AST::TagSection &TagSec = Mod.getTagSection();
101
  // This function will always success.
102
0
  instantiate(*ModInst, TagSec);
103
104
  // Push a new frame {ModInst, locals:none}
105
0
  StackMgr.pushFrame(ModInst.get(), AST::InstrView::iterator(), 0, 0);
106
107
  // Instantiate GlobalSection (GlobalSec)
108
0
  const AST::GlobalSection &GlobSec = Mod.getGlobalSection();
109
0
  EXPECTED_TRY(instantiate(StackMgr, *ModInst, GlobSec)
110
0
                   .map_error(ReportError(ASTNodeAttr::Sec_Global)));
111
112
  // Instantiate TableSection (TableSec)
113
0
  const AST::TableSection &TabSec = Mod.getTableSection();
114
0
  EXPECTED_TRY(instantiate(StackMgr, *ModInst, TabSec)
115
0
                   .map_error(ReportError(ASTNodeAttr::Sec_Table)));
116
117
  // Instantiate ExportSection (ExportSec)
118
0
  const AST::ExportSection &ExportSec = Mod.getExportSection();
119
  // This function will always success.
120
0
  instantiate(*ModInst, ExportSec);
121
122
  // Instantiate ElementSection (ElemSec)
123
0
  const AST::ElementSection &ElemSec = Mod.getElementSection();
124
0
  EXPECTED_TRY(instantiate(StackMgr, *ModInst, ElemSec)
125
0
                   .map_error(ReportError(ASTNodeAttr::Sec_Element)));
126
127
  // Instantiate DataSection (DataSec)
128
0
  const AST::DataSection &DataSec = Mod.getDataSection();
129
0
  EXPECTED_TRY(instantiate(StackMgr, *ModInst, DataSec)
130
0
                   .map_error(ReportError(ASTNodeAttr::Sec_Data)));
131
132
  // Initialize table instances
133
0
  EXPECTED_TRY(initTable(StackMgr, ElemSec)
134
0
                   .map_error(ReportError(ASTNodeAttr::Sec_Element)));
135
136
  // Initialize memory instances
137
0
  EXPECTED_TRY(initMemory(StackMgr, DataSec)
138
0
                   .map_error(ReportError(ASTNodeAttr::Sec_Data)));
139
140
  // Instantiate StartSection (StartSec)
141
0
  const AST::StartSection &StartSec = Mod.getStartSection();
142
0
  if (StartSec.getContent()) {
143
    // Get the module instance from ID.
144
0
    ModInst->setStartIdx(*StartSec.getContent());
145
146
    // Get function instance.
147
0
    const auto *FuncInst = ModInst->getStartFunc();
148
149
    // Execute instruction.
150
0
    EXPECTED_TRY(
151
0
        runFunction(StackMgr, *FuncInst, {}).map_error(ReportModuleError));
152
0
  }
153
154
  // Pop Frame.
155
0
  StackMgr.popFrame();
156
157
  // Instantiation done; finalize so the executor reads instances lock-free.
158
0
  ModInst->finalizeInstantiation();
159
160
  // For a named module, register it in the store.
161
0
  if (Name.has_value()) {
162
0
    StoreMgr.registerModule(ModInst.get());
163
0
  }
164
165
0
  return ModInst;
166
0
}
167
168
} // namespace Executor
169
} // namespace WasmEdge