Coverage Report

Created: 2026-06-30 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/lib/validator/component_context.cpp
Line
Count
Source
1
#include "validator/component_context.h"
2
3
namespace WasmEdge {
4
namespace Validator {
5
6
using Sort = AST::Component::Sort;
7
8
uint32_t
9
0
ComponentContext::Context::getSortIndexSize(Sort::SortType ST) const noexcept {
10
0
  switch (ST) {
11
0
  case Sort::SortType::Func:
12
0
    return static_cast<uint32_t>(Funcs.size());
13
0
  case Sort::SortType::Value:
14
0
    return ValueCount;
15
0
  case Sort::SortType::Type:
16
0
    return static_cast<uint32_t>(Types.size());
17
0
  case Sort::SortType::Component:
18
0
    return static_cast<uint32_t>(Components.size());
19
0
  case Sort::SortType::Instance:
20
0
    return static_cast<uint32_t>(Instances.size());
21
0
  default:
22
0
    return 0;
23
0
  }
24
0
}
25
26
uint32_t ComponentContext::Context::getCoreSortIndexSize(
27
0
    Sort::CoreSortType ST) const noexcept {
28
0
  switch (ST) {
29
0
  case Sort::CoreSortType::Func:
30
0
    return static_cast<uint32_t>(CoreFuncs.size());
31
0
  case Sort::CoreSortType::Table:
32
0
    return static_cast<uint32_t>(CoreTables.size());
33
0
  case Sort::CoreSortType::Memory:
34
0
    return static_cast<uint32_t>(CoreMemories.size());
35
0
  case Sort::CoreSortType::Global:
36
0
    return static_cast<uint32_t>(CoreGlobals.size());
37
0
  case Sort::CoreSortType::Tag:
38
0
    return CoreTagCount;
39
0
  case Sort::CoreSortType::Type:
40
0
    return static_cast<uint32_t>(CoreTypes.size());
41
0
  case Sort::CoreSortType::Module:
42
0
    return static_cast<uint32_t>(CoreModules.size());
43
0
  case Sort::CoreSortType::Instance:
44
0
    return static_cast<uint32_t>(CoreInstances.size());
45
0
  default:
46
0
    return 0;
47
0
  }
48
0
}
49
50
0
uint32_t ComponentContext::incSortIndexSize(Sort::SortType ST) noexcept {
51
0
  switch (ST) {
52
0
  case Sort::SortType::Func:
53
0
    return addFunc();
54
0
  case Sort::SortType::Value:
55
0
    return addValue();
56
0
  case Sort::SortType::Type:
57
0
    return addType();
58
0
  case Sort::SortType::Component:
59
0
    return addComponent();
60
0
  case Sort::SortType::Instance:
61
0
    return addInstance();
62
0
  default:
63
0
    return 0;
64
0
  }
65
0
}
66
67
uint32_t
68
0
ComponentContext::incCoreSortIndexSize(Sort::CoreSortType ST) noexcept {
69
0
  switch (ST) {
70
0
  case Sort::CoreSortType::Func:
71
0
    return addCoreFunc();
72
0
  case Sort::CoreSortType::Table:
73
0
    return addCoreTable();
74
0
  case Sort::CoreSortType::Memory:
75
0
    return addCoreMemory();
76
0
  case Sort::CoreSortType::Global:
77
0
    return addCoreGlobal();
78
0
  case Sort::CoreSortType::Tag:
79
0
    return addCoreTag();
80
0
  case Sort::CoreSortType::Type:
81
0
    return addCoreType();
82
0
  case Sort::CoreSortType::Module:
83
0
    return addCoreModule();
84
0
  case Sort::CoreSortType::Instance:
85
0
    return addCoreInstance();
86
0
  default:
87
0
    return 0;
88
0
  }
89
0
}
90
91
namespace {
92
constexpr std::string_view ConstructorTag{"[constructor]"};
93
94
bool addStronglyUniqueName(std::unordered_set<std::string> &Names,
95
0
                           const ComponentName &Name) noexcept {
96
0
  switch (Name.getKind()) {
97
0
  case ComponentNameKind::Constructor:
98
0
  case ComponentNameKind::Method:
99
0
  case ComponentNameKind::Static:
100
0
  case ComponentNameKind::InterfaceType:
101
0
  case ComponentNameKind::Label:
102
0
  case ComponentNameKind::LockedDep:
103
0
  case ComponentNameKind::UnlockedDep:
104
0
  case ComponentNameKind::Url:
105
0
  case ComponentNameKind::Integrity:
106
0
    break;
107
0
  default:
108
0
    return false;
109
0
  }
110
111
0
  auto toLowerString = [](std::string_view SV) {
112
0
    std::string Result = std::string(SV);
113
0
    std::transform(
114
0
        Result.begin(), Result.end(), Result.begin(),
115
0
        [](unsigned char C) { return static_cast<char>(std::tolower(C)); });
116
0
    return Result;
117
0
  };
118
119
  // Handle the Constructor case separately.
120
0
  if (Name.getKind() == ComponentNameKind::Constructor) {
121
0
    std::string LowerCase = toLowerString(Name.getOriginalName());
122
0
    std::string Label = std::string(Name.getNoTagName());
123
    // Check for conflicts with existing constructors.
124
0
    if (Names.count(LowerCase)) {
125
0
      return false;
126
0
    }
127
128
0
    if (Names.count(toLowerString(Label))) {
129
0
      if (!Names.count(Label)) {
130
0
        return false;
131
0
      }
132
      // By rule, a constructor [constructor]X and X are strongly-unique.
133
      // If X and its lower-case x form both exist, it means x comes from X.
134
0
    }
135
0
    Names.insert(LowerCase);
136
0
    Names.insert(std::string(Name.getOriginalName()));
137
0
    return true;
138
0
  }
139
140
  // For case 2, L and L.L are not strongly-unique together.
141
0
  std::string Normal = std::string(Name.getNoTagName());
142
0
  std::string UniForm = toLowerString(Normal);
143
0
  std::string LdL =
144
0
      std::string(Name.getNoTagName()) + "." + std::string(Name.getNoTagName());
145
146
0
  if (Names.count(LdL)) {
147
0
    return false;
148
0
  }
149
150
0
  if (Normal.find('.') != std::string::npos) {
151
0
    std::string Left, Right;
152
0
    size_t Pos = Normal.find('.');
153
0
    Left = Normal.substr(0, Pos);
154
0
    Right = Normal.substr(Pos + 1);
155
0
    if (Left == Right) {
156
      // Conflict with l.l and [*]l.
157
0
      if (Names.count(toLowerString(Left))) {
158
0
        return false;
159
0
      }
160
0
    }
161
0
  }
162
163
  // Case 3: check existing names.
164
0
  if (Names.count(UniForm)) {
165
0
    return false;
166
0
  }
167
168
  // Special case: check conflicts with constructor names.
169
0
  std::string ConstrName = std::string(ConstructorTag) + UniForm;
170
0
  if (Names.count(ConstrName)) {
171
0
    if (!Names.count(std::string(ConstructorTag) + Normal)) {
172
0
      return false;
173
0
    }
174
    // By rule, a constructor [constructor]X and X are strongly-unique.
175
    // If [constructor]X and its lower-case [constructor]x form both exist, it
176
    // means [constructor]x comes from [constructor]X.
177
0
  }
178
0
  Names.insert(Normal);
179
0
  Names.insert(UniForm);
180
0
  return true;
181
0
}
182
} // namespace
183
184
bool ComponentContext::Context::AddImportedName(
185
0
    const ComponentName &Name) noexcept {
186
0
  return addStronglyUniqueName(ImportedNames, Name);
187
0
}
188
189
bool ComponentContext::Context::AddExportedName(
190
0
    const ComponentName &Name) noexcept {
191
0
  return addStronglyUniqueName(ExportedNames, Name);
192
0
}
193
} // namespace Validator
194
} // namespace WasmEdge