Coverage Report

Created: 2026-08-13 06: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
43.5k
ComponentContext::Context::getSortIndexSize(Sort::SortType ST) const noexcept {
10
43.5k
  switch (ST) {
11
1.97k
  case Sort::SortType::Func:
12
1.97k
    return static_cast<uint32_t>(Funcs.size());
13
1.82k
  case Sort::SortType::Value:
14
1.82k
    return ValueCount;
15
34.1k
  case Sort::SortType::Type:
16
34.1k
    return static_cast<uint32_t>(Types.size());
17
3.38k
  case Sort::SortType::Component:
18
3.38k
    return static_cast<uint32_t>(Components.size());
19
2.21k
  case Sort::SortType::Instance:
20
2.21k
    return static_cast<uint32_t>(Instances.size());
21
0
  default:
22
0
    return 0;
23
43.5k
  }
24
43.5k
}
25
26
uint32_t ComponentContext::Context::getCoreSortIndexSize(
27
14.4k
    Sort::CoreSortType ST) const noexcept {
28
14.4k
  switch (ST) {
29
13.0k
  case Sort::CoreSortType::Func:
30
13.0k
    return static_cast<uint32_t>(CoreFuncs.size());
31
101
  case Sort::CoreSortType::Table:
32
101
    return static_cast<uint32_t>(CoreTables.size());
33
21
  case Sort::CoreSortType::Memory:
34
21
    return static_cast<uint32_t>(CoreMemories.size());
35
3
  case Sort::CoreSortType::Global:
36
3
    return static_cast<uint32_t>(CoreGlobals.size());
37
14
  case Sort::CoreSortType::Tag:
38
14
    return CoreTagCount;
39
513
  case Sort::CoreSortType::Type:
40
513
    return static_cast<uint32_t>(CoreTypes.size());
41
323
  case Sort::CoreSortType::Module:
42
323
    return static_cast<uint32_t>(CoreModules.size());
43
375
  case Sort::CoreSortType::Instance:
44
375
    return static_cast<uint32_t>(CoreInstances.size());
45
0
  default:
46
0
    return 0;
47
14.4k
  }
48
14.4k
}
49
50
5.54k
uint32_t ComponentContext::incSortIndexSize(Sort::SortType ST) noexcept {
51
5.54k
  switch (ST) {
52
9
  case Sort::SortType::Func:
53
9
    return addFunc();
54
594
  case Sort::SortType::Value:
55
594
    return addValue();
56
3.33k
  case Sort::SortType::Type:
57
3.33k
    return addType();
58
422
  case Sort::SortType::Component:
59
422
    return addComponent();
60
1.18k
  case Sort::SortType::Instance:
61
1.18k
    return addInstance();
62
0
  default:
63
0
    return 0;
64
5.54k
  }
65
5.54k
}
66
67
uint32_t
68
752
ComponentContext::incCoreSortIndexSize(Sort::CoreSortType ST) noexcept {
69
752
  switch (ST) {
70
313
  case Sort::CoreSortType::Func:
71
313
    return addCoreFunc();
72
78
  case Sort::CoreSortType::Table:
73
78
    return addCoreTable();
74
12
  case Sort::CoreSortType::Memory:
75
12
    return addCoreMemory();
76
1
  case Sort::CoreSortType::Global:
77
1
    return addCoreGlobal();
78
6
  case Sort::CoreSortType::Tag:
79
6
    return addCoreTag();
80
342
  case Sort::CoreSortType::Type:
81
342
    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
752
  }
89
752
}
90
91
namespace {
92
constexpr std::string_view ConstructorTag{"[constructor]"};
93
94
bool addStronglyUniqueName(std::unordered_set<std::string> &Names,
95
5.98k
                           const ComponentName &Name) noexcept {
96
5.98k
  switch (Name.getKind()) {
97
255
  case ComponentNameKind::Constructor:
98
255
  case ComponentNameKind::Method:
99
296
  case ComponentNameKind::Static:
100
2.16k
  case ComponentNameKind::InterfaceType:
101
5.95k
  case ComponentNameKind::Label:
102
5.95k
  case ComponentNameKind::LockedDep:
103
5.95k
  case ComponentNameKind::UnlockedDep:
104
5.96k
  case ComponentNameKind::Url:
105
5.98k
  case ComponentNameKind::Integrity:
106
5.98k
    break;
107
0
  default:
108
0
    return false;
109
5.98k
  }
110
111
6.24k
  auto toLowerString = [](std::string_view SV) {
112
6.24k
    std::string Result = std::string(SV);
113
6.24k
    std::transform(
114
6.24k
        Result.begin(), Result.end(), Result.begin(),
115
60.1k
        [](unsigned char C) { return static_cast<char>(std::tolower(C)); });
116
6.24k
    return Result;
117
6.24k
  };
118
119
  // Handle the Constructor case separately.
120
5.98k
  if (Name.getKind() == ComponentNameKind::Constructor) {
121
255
    std::string LowerCase = toLowerString(Name.getOriginalName());
122
255
    std::string Label = std::string(Name.getNoTagName());
123
    // Check for conflicts with existing constructors.
124
255
    if (Names.count(LowerCase)) {
125
3
      return false;
126
3
    }
127
128
252
    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
252
    Names.insert(LowerCase);
136
252
    Names.insert(std::string(Name.getOriginalName()));
137
252
    return true;
138
252
  }
139
140
  // For case 2, L and L.L are not strongly-unique together.
141
5.72k
  std::string Normal = std::string(Name.getNoTagName());
142
5.72k
  std::string UniForm = toLowerString(Normal);
143
5.72k
  std::string LdL =
144
5.72k
      std::string(Name.getNoTagName()) + "." + std::string(Name.getNoTagName());
145
146
5.72k
  if (Names.count(LdL)) {
147
0
    return false;
148
0
  }
149
150
5.72k
  if (Normal.find('.') != std::string::npos) {
151
377
    std::string Left, Right;
152
377
    size_t Pos = Normal.find('.');
153
377
    Left = Normal.substr(0, Pos);
154
377
    Right = Normal.substr(Pos + 1);
155
377
    if (Left == Right) {
156
      // Conflict with l.l and [*]l.
157
14
      if (Names.count(toLowerString(Left))) {
158
0
        return false;
159
0
      }
160
14
    }
161
377
  }
162
163
  // Case 3: check existing names.
164
5.72k
  if (Names.count(UniForm)) {
165
81
    return false;
166
81
  }
167
168
  // Special case: check conflicts with constructor names.
169
5.64k
  std::string ConstrName = std::string(ConstructorTag) + UniForm;
170
5.64k
  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
5.64k
  Names.insert(Normal);
179
5.64k
  Names.insert(UniForm);
180
5.64k
  return true;
181
5.64k
}
182
} // namespace
183
184
bool ComponentContext::Context::AddImportedName(
185
5.10k
    const ComponentName &Name) noexcept {
186
5.10k
  return addStronglyUniqueName(ImportedNames, Name);
187
5.10k
}
188
189
bool ComponentContext::Context::AddExportedName(
190
878
    const ComponentName &Name) noexcept {
191
878
  return addStronglyUniqueName(ExportedNames, Name);
192
878
}
193
} // namespace Validator
194
} // namespace WasmEdge