Coverage Report

Created: 2025-08-25 06:58

/src/WasmEdge/include/validator/component_context.h
Line
Count
Source (jump to first uncovered line)
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: 2019-2024 Second State INC
3
#pragma once
4
5
#include "ast/component/component.h"
6
#include "ast/module.h"
7
8
#include <deque>
9
#include <optional>
10
#include <unordered_map>
11
#include <vector>
12
13
namespace WasmEdge {
14
namespace Validator {
15
16
class ComponentContext {
17
public:
18
  struct Context {
19
    const AST::Component::Component *Component;
20
    std::vector<const AST::Module *> CoreModules;
21
    std::vector<const AST::Component::Component *> ChildComponents;
22
    const Context *Parent;
23
    std::vector<uint32_t> SortIndexSizes;
24
    std::vector<uint32_t> CoreSortIndexSizes;
25
    std::unordered_map<std::string, uint32_t> TypeSubstitutions;
26
    std::unordered_map<uint32_t,
27
                       std::unordered_map<std::string_view,
28
                                          const AST::Component::ExternDesc *>>
29
        ComponentInstanceExports;
30
    std::unordered_map<uint32_t,
31
                       std::unordered_map<std::string_view, ExternalType>>
32
        CoreInstanceExports;
33
    std::unordered_map<uint32_t, const AST::Component::InstanceType *>
34
        ComponentInstanceTypes;
35
    std::unordered_map<uint32_t, const AST::Component::ResourceType *>
36
        ComponentResourceTypes;
37
38
    Context(const AST::Component::Component *C,
39
            const Context *P = nullptr) noexcept
40
0
        : Component(C), Parent(P), SortIndexSizes(static_cast<uint32_t>(
41
0
                                       AST::Component::Sort::SortType::Max)),
42
0
          CoreSortIndexSizes(
43
0
              static_cast<uint32_t>(AST::Component::Sort::CoreSortType::Max)) {}
44
45
    uint32_t
46
0
    getSortIndexSize(const AST::Component::Sort::SortType ST) const noexcept {
47
0
      return SortIndexSizes[static_cast<uint32_t>(ST)];
48
0
    }
49
50
    uint32_t getCoreSortIndexSize(
51
0
        const AST::Component::Sort::CoreSortType ST) const noexcept {
52
0
      return CoreSortIndexSizes[static_cast<uint32_t>(ST)];
53
0
    }
54
  };
55
56
0
  void enterComponent(const AST::Component::Component &C) noexcept {
57
0
    const Context *Parent = nullptr;
58
0
    if (!CompCtxs.empty()) {
59
0
      CompCtxs.back().ChildComponents.emplace_back(&C);
60
0
      Parent = &CompCtxs.back();
61
0
    }
62
0
    CompCtxs.emplace_back(&C, Parent);
63
0
  }
64
65
0
  void exitComponent() noexcept {
66
0
    assuming(!CompCtxs.empty());
67
0
    if (!CompCtxs.empty()) {
68
0
      CompCtxs.pop_back();
69
0
    }
70
0
  }
71
72
0
  Context &getCurrentContext() noexcept {
73
0
    assuming(!CompCtxs.empty());
74
0
    return CompCtxs.back();
75
0
  }
76
77
0
  const Context &getCurrentContext() const noexcept {
78
0
    assuming(!CompCtxs.empty());
79
0
    return CompCtxs.back();
80
0
  }
81
82
0
  void addCoreModule(const AST::Module &M) noexcept {
83
0
    getCurrentContext().CoreModules.emplace_back(&M);
84
0
  }
85
86
0
  const AST::Module &getCoreModule(const uint32_t Index) const noexcept {
87
0
    return *getCurrentContext().CoreModules.at(Index);
88
0
  }
89
90
0
  uint32_t getCoreModuleCount() const noexcept {
91
0
    return static_cast<uint32_t>(getCurrentContext().CoreModules.size());
92
0
  }
93
94
  const AST::Component::Component &
95
0
  getComponent(const uint32_t Index) const noexcept {
96
0
    return *getCurrentContext().ChildComponents.at(Index);
97
0
  }
98
99
0
  uint32_t getComponentCount() const noexcept {
100
0
    return static_cast<uint32_t>(getCurrentContext().ChildComponents.size());
101
0
  }
102
103
0
  const Context *getParentContext() const noexcept {
104
0
    return getCurrentContext().Parent;
105
0
  }
106
107
  uint32_t
108
0
  getSortIndexSize(const AST::Component::Sort::SortType ST) const noexcept {
109
0
    return getCurrentContext().getSortIndexSize(ST);
110
0
  }
111
112
  uint32_t getCoreSortIndexSize(
113
0
      const AST::Component::Sort::CoreSortType ST) const noexcept {
114
0
    return getCurrentContext().getCoreSortIndexSize(ST);
115
0
  }
116
117
0
  void incSortIndexSize(const AST::Component::Sort::SortType ST) noexcept {
118
0
    getCurrentContext().SortIndexSizes[static_cast<uint32_t>(ST)]++;
119
0
  }
120
121
  void
122
0
  incCoreSortIndexSize(const AST::Component::Sort::CoreSortType ST) noexcept {
123
0
    getCurrentContext().CoreSortIndexSizes[static_cast<uint32_t>(ST)]++;
124
0
  }
125
126
  void substituteTypeImport(const std::string &ImportName,
127
0
                            const uint32_t TypeIdx) noexcept {
128
0
    getCurrentContext().TypeSubstitutions[ImportName] = TypeIdx;
129
0
  }
130
131
  std::optional<uint32_t>
132
0
  getSubstitutedType(const std::string &ImportName) const {
133
0
    const auto &Ctx = getCurrentContext();
134
0
    auto It = Ctx.TypeSubstitutions.find(ImportName);
135
0
    if (It != Ctx.TypeSubstitutions.end()) {
136
0
      return It->second;
137
0
    }
138
0
    return std::nullopt;
139
0
  }
140
141
  void addComponentInstanceExport(uint32_t InstanceIdx,
142
                                  const std::string_view &ExportName,
143
0
                                  const AST::Component::ExternDesc &ED) {
144
0
    auto &Ctx = getCurrentContext();
145
0
    Ctx.ComponentInstanceExports[InstanceIdx][ExportName] = &ED;
146
0
  }
147
148
  std::unordered_map<std::string_view, const AST::Component::ExternDesc *>
149
0
  getComponentInstanceExports(uint32_t InstanceIdx) const {
150
0
    const auto &Ctx = getCurrentContext();
151
0
    auto It = Ctx.ComponentInstanceExports.find(InstanceIdx);
152
0
    if (It != Ctx.ComponentInstanceExports.end()) {
153
0
      return It->second;
154
0
    }
155
0
    return {};
156
0
  }
157
158
0
  uint32_t getComponentInstanceExportsSize() const {
159
0
    const auto &Exports = getCurrentContext().ComponentInstanceExports;
160
0
    if (Exports.empty()) {
161
0
      return 0;
162
0
    }
163
164
0
    uint32_t MaxIdx = 0;
165
0
    for (const auto &Pair : Exports) {
166
0
      if (Pair.first > MaxIdx) {
167
0
        MaxIdx = Pair.first;
168
0
      }
169
0
    }
170
0
    return MaxIdx + 1;
171
0
  }
172
173
  void addCoreInstanceExport(uint32_t InstanceIdx,
174
                             const std::string_view &ExportName,
175
0
                             const ExternalType &ET) {
176
0
    auto &Ctx = getCurrentContext();
177
0
    Ctx.CoreInstanceExports[InstanceIdx][ExportName] = ET;
178
0
  }
179
180
  std::unordered_map<std::string_view, ExternalType>
181
0
  getCoreInstanceExports(uint32_t InstanceIdx) const {
182
0
    const auto &Ctx = getCurrentContext();
183
0
    auto It = Ctx.CoreInstanceExports.find(InstanceIdx);
184
0
    if (It != Ctx.CoreInstanceExports.end()) {
185
0
      return It->second;
186
0
    }
187
0
    return {};
188
0
  }
189
190
0
  uint32_t getCoreInstanceExportsSize() const {
191
0
    const auto &Exports = getCurrentContext().CoreInstanceExports;
192
0
    if (Exports.empty()) {
193
0
      return 0;
194
0
    }
195
196
0
    uint32_t MaxIdx = 0;
197
0
    for (const auto &Pair : Exports) {
198
0
      if (Pair.first > MaxIdx) {
199
0
        MaxIdx = Pair.first;
200
0
      }
201
0
    }
202
0
    return MaxIdx + 1;
203
0
  }
204
205
  void addComponentInstanceType(uint32_t Idx,
206
0
                                const AST::Component::InstanceType &IT) {
207
0
    auto &Ctx = getCurrentContext();
208
0
    Ctx.ComponentInstanceTypes[Idx] = &IT;
209
0
  }
210
211
  const AST::Component::InstanceType *
212
0
  getComponentInstanceType(uint32_t Idx) const {
213
0
    const auto &Ctx = getCurrentContext();
214
0
    auto It = Ctx.ComponentInstanceTypes.find(Idx);
215
0
    if (It != Ctx.ComponentInstanceTypes.end()) {
216
0
      return It->second;
217
0
    } else {
218
0
      return nullptr;
219
0
    }
220
0
  }
221
222
  void addComponentResourceType(uint32_t Idx,
223
0
                                const AST::Component::ResourceType &IT) {
224
0
    auto &Ctx = getCurrentContext();
225
0
    Ctx.ComponentResourceTypes[Idx] = &IT;
226
0
  }
227
228
  const AST::Component::ResourceType *
229
0
  getComponentResourceType(uint32_t Idx) const {
230
0
    const auto &Ctx = getCurrentContext();
231
0
    auto It = Ctx.ComponentResourceTypes.find(Idx);
232
0
233
0
    if (It != Ctx.ComponentResourceTypes.end()) {
234
0
      return It->second;
235
0
    } else {
236
0
      return nullptr;
237
0
    }
238
0
  }
239
240
private:
241
  std::deque<Context> CompCtxs;
242
};
243
244
} // namespace Validator
245
} // namespace WasmEdge