Coverage Report

Created: 2025-07-01 06:18

/src/WasmEdge/lib/executor/instantiate/module.cpp
Line
Count
Source (jump to first uncovered line)
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: 2019-2024 Second State INC
3
4
#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 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 is module name duplicated when trying to 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 to store manager and retrieve instance.
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(StoreMgr, *ModInst, ImportSec)
71
0
                   .map_error(ReportError(ASTNodeAttr::Sec_Import)));
72
73
  // Instantiate Functions in module. (FunctionSec, CodeSec)
74
0
  const AST::FunctionSection &FuncSec = Mod.getFunctionSection();
75
0
  const AST::CodeSection &CodeSec = Mod.getCodeSection();
76
  // This function will always success.
77
0
  instantiate(*ModInst, FuncSec, CodeSec);
78
79
  // Instantiate MemorySection (MemorySec)
80
0
  const AST::MemorySection &MemSec = Mod.getMemorySection();
81
  // This function will always success.
82
0
  instantiate(*ModInst, MemSec);
83
84
  // Instantiate TagSection (TagSec)
85
0
  const AST::TagSection &TagSec = Mod.getTagSection();
86
  // This function will always success.
87
0
  instantiate(*ModInst, TagSec);
88
89
  // Push a new frame {ModInst, locals:none}
90
0
  StackMgr.pushFrame(ModInst.get(), AST::InstrView::iterator(), 0, 0);
91
92
  // Instantiate GlobalSection (GlobalSec)
93
0
  const AST::GlobalSection &GlobSec = Mod.getGlobalSection();
94
0
  EXPECTED_TRY(instantiate(StackMgr, *ModInst, GlobSec)
95
0
                   .map_error(ReportError(ASTNodeAttr::Sec_Global)));
96
97
  // Instantiate TableSection (TableSec)
98
0
  const AST::TableSection &TabSec = Mod.getTableSection();
99
0
  EXPECTED_TRY(instantiate(StackMgr, *ModInst, TabSec)
100
0
                   .map_error(ReportError(ASTNodeAttr::Sec_Table)));
101
102
  // Instantiate ExportSection (ExportSec)
103
0
  const AST::ExportSection &ExportSec = Mod.getExportSection();
104
  // This function will always success.
105
0
  instantiate(*ModInst, ExportSec);
106
107
  // Instantiate ElementSection (ElemSec)
108
0
  const AST::ElementSection &ElemSec = Mod.getElementSection();
109
0
  EXPECTED_TRY(instantiate(StackMgr, *ModInst, ElemSec)
110
0
                   .map_error(ReportError(ASTNodeAttr::Sec_Element)));
111
112
  // Instantiate DataSection (DataSec)
113
0
  const AST::DataSection &DataSec = Mod.getDataSection();
114
0
  EXPECTED_TRY(instantiate(StackMgr, *ModInst, DataSec)
115
0
                   .map_error(ReportError(ASTNodeAttr::Sec_Data)));
116
117
  // Initialize table instances
118
0
  EXPECTED_TRY(initTable(StackMgr, ElemSec)
119
0
                   .map_error(ReportError(ASTNodeAttr::Sec_Element)));
120
121
  // Initialize memory instances
122
0
  EXPECTED_TRY(initMemory(StackMgr, DataSec)
123
0
                   .map_error(ReportError(ASTNodeAttr::Sec_Data)));
124
125
  // Instantiate StartSection (StartSec)
126
0
  const AST::StartSection &StartSec = Mod.getStartSection();
127
0
  if (StartSec.getContent()) {
128
    // Get the module instance from ID.
129
0
    ModInst->setStartIdx(*StartSec.getContent());
130
131
    // Get function instance.
132
0
    const auto *FuncInst = ModInst->getStartFunc();
133
134
    // Execute instruction.
135
0
    EXPECTED_TRY(
136
0
        runFunction(StackMgr, *FuncInst, {}).map_error(ReportModuleError));
137
0
  }
138
139
  // Pop Frame.
140
0
  StackMgr.popFrame();
141
142
  // For the named modules, register it into the store.
143
0
  if (Name.has_value()) {
144
0
    StoreMgr.registerModule(ModInst.get());
145
0
  }
146
147
0
  return ModInst;
148
0
}
149
150
} // namespace Executor
151
} // namespace WasmEdge