Coverage Report

Created: 2026-07-16 07:09

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
22.6k
ComponentContext::Context::getSortIndexSize(Sort::SortType ST) const noexcept {
10
22.6k
  switch (ST) {
11
1.54k
  case Sort::SortType::Func:
12
1.54k
    return static_cast<uint32_t>(Funcs.size());
13
982
  case Sort::SortType::Value:
14
982
    return ValueCount;
15
18.1k
  case Sort::SortType::Type:
16
18.1k
    return static_cast<uint32_t>(Types.size());
17
1.48k
  case Sort::SortType::Component:
18
1.48k
    return static_cast<uint32_t>(Components.size());
19
443
  case Sort::SortType::Instance:
20
443
    return static_cast<uint32_t>(Instances.size());
21
0
  default:
22
0
    return 0;
23
22.6k
  }
24
22.6k
}
25
26
uint32_t ComponentContext::Context::getCoreSortIndexSize(
27
3.68k
    Sort::CoreSortType ST) const noexcept {
28
3.68k
  switch (ST) {
29
3.26k
  case Sort::CoreSortType::Func:
30
3.26k
    return static_cast<uint32_t>(CoreFuncs.size());
31
7
  case Sort::CoreSortType::Table:
32
7
    return static_cast<uint32_t>(CoreTables.size());
33
6
  case Sort::CoreSortType::Memory:
34
6
    return static_cast<uint32_t>(CoreMemories.size());
35
8
  case Sort::CoreSortType::Global:
36
8
    return static_cast<uint32_t>(CoreGlobals.size());
37
10
  case Sort::CoreSortType::Tag:
38
10
    return CoreTagCount;
39
267
  case Sort::CoreSortType::Type:
40
267
    return static_cast<uint32_t>(CoreTypes.size());
41
55
  case Sort::CoreSortType::Module:
42
55
    return static_cast<uint32_t>(CoreModules.size());
43
69
  case Sort::CoreSortType::Instance:
44
69
    return static_cast<uint32_t>(CoreInstances.size());
45
0
  default:
46
0
    return 0;
47
3.68k
  }
48
3.68k
}
49
50
1.35k
uint32_t ComponentContext::incSortIndexSize(Sort::SortType ST) noexcept {
51
1.35k
  switch (ST) {
52
1
  case Sort::SortType::Func:
53
1
    return addFunc();
54
687
  case Sort::SortType::Value:
55
687
    return addValue();
56
535
  case Sort::SortType::Type:
57
535
    return addType();
58
26
  case Sort::SortType::Component:
59
26
    return addComponent();
60
101
  case Sort::SortType::Instance:
61
101
    return addInstance();
62
0
  default:
63
0
    return 0;
64
1.35k
  }
65
1.35k
}
66
67
uint32_t
68
101
ComponentContext::incCoreSortIndexSize(Sort::CoreSortType ST) noexcept {
69
101
  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
101
  case Sort::CoreSortType::Type:
81
101
    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
101
  }
89
101
}
90
91
namespace {
92
constexpr std::string_view ConstructorTag{"[constructor]"};
93
94
bool addStronglyUniqueName(std::unordered_set<std::string> &Names,
95
4.72k
                           const ComponentName &Name) noexcept {
96
4.72k
  switch (Name.getKind()) {
97
311
  case ComponentNameKind::Constructor:
98
311
  case ComponentNameKind::Method:
99
347
  case ComponentNameKind::Static:
100
2.77k
  case ComponentNameKind::InterfaceType:
101
4.71k
  case ComponentNameKind::Label:
102
4.71k
  case ComponentNameKind::LockedDep:
103
4.71k
  case ComponentNameKind::UnlockedDep:
104
4.72k
  case ComponentNameKind::Url:
105
4.72k
  case ComponentNameKind::Integrity:
106
4.72k
    break;
107
0
  default:
108
0
    return false;
109
4.72k
  }
110
111
5.04k
  auto toLowerString = [](std::string_view SV) {
112
5.04k
    std::string Result = std::string(SV);
113
5.04k
    std::transform(
114
5.04k
        Result.begin(), Result.end(), Result.begin(),
115
69.4k
        [](unsigned char C) { return static_cast<char>(std::tolower(C)); });
116
5.04k
    return Result;
117
5.04k
  };
118
119
  // Handle the Constructor case separately.
120
4.72k
  if (Name.getKind() == ComponentNameKind::Constructor) {
121
311
    std::string LowerCase = toLowerString(Name.getOriginalName());
122
311
    std::string Label = std::string(Name.getNoTagName());
123
    // Check for conflicts with existing constructors.
124
311
    if (Names.count(LowerCase)) {
125
2
      return false;
126
2
    }
127
128
309
    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
309
    Names.insert(LowerCase);
136
309
    Names.insert(std::string(Name.getOriginalName()));
137
309
    return true;
138
309
  }
139
140
  // For case 2, L and L.L are not strongly-unique together.
141
4.41k
  std::string Normal = std::string(Name.getNoTagName());
142
4.41k
  std::string UniForm = toLowerString(Normal);
143
4.41k
  std::string LdL =
144
4.41k
      std::string(Name.getNoTagName()) + "." + std::string(Name.getNoTagName());
145
146
4.41k
  if (Names.count(LdL)) {
147
0
    return false;
148
0
  }
149
150
4.41k
  if (Normal.find('.') != std::string::npos) {
151
708
    std::string Left, Right;
152
708
    size_t Pos = Normal.find('.');
153
708
    Left = Normal.substr(0, Pos);
154
708
    Right = Normal.substr(Pos + 1);
155
708
    if (Left == Right) {
156
      // Conflict with l.l and [*]l.
157
4
      if (Names.count(toLowerString(Left))) {
158
0
        return false;
159
0
      }
160
4
    }
161
708
  }
162
163
  // Case 3: check existing names.
164
4.41k
  if (Names.count(UniForm)) {
165
116
    return false;
166
116
  }
167
168
  // Special case: check conflicts with constructor names.
169
4.30k
  std::string ConstrName = std::string(ConstructorTag) + UniForm;
170
4.30k
  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
4.30k
  Names.insert(Normal);
179
4.30k
  Names.insert(UniForm);
180
4.30k
  return true;
181
4.30k
}
182
} // namespace
183
184
bool ComponentContext::Context::AddImportedName(
185
3.99k
    const ComponentName &Name) noexcept {
186
3.99k
  return addStronglyUniqueName(ImportedNames, Name);
187
3.99k
}
188
189
bool ComponentContext::Context::AddExportedName(
190
731
    const ComponentName &Name) noexcept {
191
731
  return addStronglyUniqueName(ExportedNames, Name);
192
731
}
193
} // namespace Validator
194
} // namespace WasmEdge