Coverage Report

Created: 2026-11-09 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/lib/loader/ast/component/component.cpp
Line
Count
Source
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright The WasmEdge Authors
3
4
#include "loader/loader.h"
5
6
using namespace std::literals;
7
8
namespace WasmEdge {
9
namespace Loader {
10
11
127k
Expect<std::pair<std::vector<Byte>, std::vector<Byte>>> Loader::loadPreamble() {
12
  // component ::= <preamble> s*:<section>* => (component flatten(s*))
13
  // preamble  ::= <magic> <version> <layer>
14
  // magic     ::= 0x00 0x61 0x73 0x6D
15
  // version   ::= 0x0d 0x00
16
  // layer     ::= 0x01 0x00
17
18
  // The combination of version and layer corresponds to the version of core
19
  // wasm.
20
  // The core module has the same magic but a different version:
21
  // 0x01 0x00 0x00 0x00
22
127k
  auto Magic = FMgr.readBytes(4);
23
127k
  if (!Magic) {
24
109
    return logLoadError(Magic.error(), FMgr.getLastOffset(),
25
109
                        ASTNodeAttr::Module);
26
109
  }
27
127k
  std::vector<Byte> WasmMagic = {0x00, 0x61, 0x73, 0x6D};
28
127k
  if (*Magic != WasmMagic) {
29
115
    auto M = *Magic;
30
115
    spdlog::error("Might an invalid wasm file, magic expected, but got 0x{:X} "
31
115
                  "0x{:X} 0x{:X} 0x{:X}"sv,
32
115
                  M[0], M[1], M[2], M[3]);
33
115
    return logLoadError(ErrCode::Value::MalformedMagic, FMgr.getLastOffset(),
34
115
                        ASTNodeAttr::Module);
35
115
  }
36
127k
  auto Ver = FMgr.readBytes(4);
37
127k
  if (!Ver) {
38
5
    return logLoadError(Ver.error(), FMgr.getLastOffset(), ASTNodeAttr::Module);
39
5
  }
40
127k
  return std::make_pair(*Magic, *Ver);
41
127k
}
42
43
Expect<void> Loader::loadComponent(AST::Component::Component &Comp,
44
94.5k
                                   std::optional<uint64_t> Bound) {
45
94.5k
  ComponentNestGuard NestGuard(ComponentNestLevel);
46
94.5k
  if (unlikely(ComponentNestLevel > MaxComponentNestLevel)) {
47
1
    return logLoadError(ErrCode::Value::ComponentNestLevelExceeded,
48
1
                        FMgr.getLastOffset(), ASTNodeAttr::Component);
49
1
  }
50
94.5k
  auto ReportError = [](auto E) {
51
5.34k
    spdlog::error(ErrInfo::InfoAST(ASTNodeAttr::Component));
52
5.34k
    return E;
53
5.34k
  };
54
  // component ::= <preamble> s*:<section>*           => (component flatten(s*))
55
  // section   ::=    section_0(<core:custom>)        => ϵ
56
  //             | m: section_1(<core:module>)        => [core-prefix(m)]
57
  //             | i*:section_2(vec(<core:instance>)) => core-prefix(i)*
58
  //             | t*:section_3(vec(<core:type>))     => core-prefix(t)*
59
  //             | c: section_4(<component>)          => [c]
60
  //             | i*:section_5(vec(<instance>))      => i*
61
  //             | a*:section_6(vec(<alias>))         => a*
62
  //             | t*:section_7(vec(<type>))          => t*
63
  //             | c*:section_8(vec(<canon>))         => c*
64
  //             | s: section_9(<start>)              => [s]
65
  //             | i*:section_10(vec(<import>))       => i*
66
  //             | e*:section_11(vec(<export>))       => e*
67
  //             | v*:section_12(vec(<value>))        => v* 🪙
68
94.5k
  uint64_t StartOffset = FMgr.getOffset();
69
94.5k
  uint64_t Offset = FMgr.getOffset();
70
94.5k
  Expect<Byte> ResSecId;
71
72
15.7M
  while ((!Bound.has_value() || *Bound > Offset - StartOffset) &&
73
15.6M
         (ResSecId = FMgr.readByte())) {
74
15.6M
    if (!ResSecId) {
75
0
      return logLoadError(ResSecId.error(), FMgr.getLastOffset(),
76
0
                          ASTNodeAttr::Component);
77
0
    }
78
    // keep going only if we have new section ID
79
15.6M
    uint8_t NewSectionId = *ResSecId;
80
15.6M
    Comp.getSections().emplace_back();
81
15.6M
    auto &Sec = Comp.getSections().back();
82
83
15.6M
    switch (NewSectionId) {
84
5.76M
    case 0x00:
85
5.76M
      EXPECTED_TRY(loadSection(Sec.emplace<AST::CustomSection>())
86
5.76M
                       .map_error(ReportError));
87
5.76M
      break;
88
5.76M
    case 0x01:
89
12.1k
      EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::CoreModuleSection>())
90
11.9k
                       .map_error(ReportError));
91
11.9k
      break;
92
133k
    case 0x02:
93
133k
      EXPECTED_TRY(
94
133k
          loadSection(Sec.emplace<AST::Component::CoreInstanceSection>())
95
133k
              .map_error(ReportError));
96
133k
      break;
97
269k
    case 0x03:
98
269k
      EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::CoreTypeSection>())
99
268k
                       .map_error(ReportError));
100
268k
      break;
101
268k
    case 0x04:
102
83.8k
      EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::ComponentSection>())
103
82.6k
                       .map_error(ReportError));
104
82.6k
      break;
105
2.28M
    case 0x05:
106
2.28M
      EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::InstanceSection>())
107
2.28M
                       .map_error(ReportError));
108
2.28M
      break;
109
2.28M
    case 0x06:
110
85.2k
      EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::AliasSection>())
111
85.0k
                       .map_error(ReportError));
112
85.0k
      break;
113
6.59M
    case 0x07:
114
6.59M
      EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::TypeSection>())
115
6.59M
                       .map_error(ReportError));
116
6.59M
      break;
117
6.59M
    case 0x08:
118
287k
      EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::CanonSection>())
119
287k
                       .map_error(ReportError));
120
287k
      break;
121
287k
    case 0x09:
122
1.22k
      EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::StartSection>())
123
1.12k
                       .map_error(ReportError));
124
1.12k
      break;
125
115k
    case 0x0A:
126
115k
      EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::ImportSection>())
127
115k
                       .map_error(ReportError));
128
115k
      break;
129
115k
    case 0x0B:
130
17.5k
      EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::ExportSection>())
131
17.4k
                       .map_error(ReportError));
132
17.4k
      break;
133
17.4k
    case 0x0C:
134
16.0k
      EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::ValueSection>())
135
15.8k
                       .map_error(ReportError));
136
15.8k
      break;
137
15.8k
    default:
138
46
      return logLoadError(ErrCode::Value::MalformedSection,
139
46
                          FMgr.getLastOffset(), ASTNodeAttr::Component);
140
15.6M
    }
141
15.6M
    Offset = FMgr.getOffset();
142
15.6M
  }
143
89.1k
  return {};
144
94.5k
}
145
146
} // namespace Loader
147
} // namespace WasmEdge