Coverage Report

Created: 2026-08-08 06:32

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