/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 | 39.2k | 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 ::= 0x0a 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 | 39.2k | auto Magic = FMgr.readBytes(4); |
23 | 39.2k | if (!Magic) { |
24 | 93 | return logLoadError(Magic.error(), FMgr.getLastOffset(), |
25 | 93 | ASTNodeAttr::Module); |
26 | 93 | } |
27 | 39.1k | std::vector<Byte> WasmMagic = {0x00, 0x61, 0x73, 0x6D}; |
28 | 39.1k | if (*Magic != WasmMagic) { |
29 | 118 | auto M = *Magic; |
30 | 118 | spdlog::error("Might an invalid wasm file, magic expected, but got 0x{:X} " |
31 | 118 | "0x{:X} 0x{:X} 0x{:X}"sv, |
32 | 118 | M[0], M[1], M[2], M[3]); |
33 | 118 | return logLoadError(ErrCode::Value::MalformedMagic, FMgr.getLastOffset(), |
34 | 118 | ASTNodeAttr::Module); |
35 | 118 | } |
36 | 38.9k | auto Ver = FMgr.readBytes(4); |
37 | 38.9k | if (!Ver) { |
38 | 3 | return logLoadError(Ver.error(), FMgr.getLastOffset(), ASTNodeAttr::Module); |
39 | 3 | } |
40 | 38.9k | return std::make_pair(*Magic, *Ver); |
41 | 38.9k | } |
42 | | |
43 | | Expect<void> Loader::loadComponent(AST::Component::Component &Comp, |
44 | 15.4k | std::optional<uint64_t> Bound) { |
45 | 15.4k | ComponentNestGuard NestGuard(ComponentNestLevel); |
46 | 15.4k | if (unlikely(ComponentNestLevel > MaxComponentNestLevel)) { |
47 | 1 | return logLoadError(ErrCode::Value::ComponentNestLevelExceeded, |
48 | 1 | FMgr.getLastOffset(), ASTNodeAttr::Component); |
49 | 1 | } |
50 | 15.4k | auto ReportError = [](auto E) { |
51 | 5.03k | spdlog::error(ErrInfo::InfoAST(ASTNodeAttr::Component)); |
52 | 5.03k | return E; |
53 | 5.03k | }; |
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 | 15.4k | uint64_t StartOffset = FMgr.getOffset(); |
69 | 15.4k | uint64_t Offset = FMgr.getOffset(); |
70 | 15.4k | Expect<Byte> ResSecId; |
71 | | |
72 | 4.63M | while ((!Bound.has_value() || *Bound > Offset - StartOffset) && |
73 | 4.62M | (ResSecId = FMgr.readByte())) { |
74 | 4.61M | 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 | 4.61M | uint8_t NewSectionId = *ResSecId; |
80 | 4.61M | Comp.getSections().emplace_back(); |
81 | 4.61M | auto &Sec = Comp.getSections().back(); |
82 | | |
83 | 4.61M | switch (NewSectionId) { |
84 | 2.04M | case 0x00: |
85 | 2.04M | EXPECTED_TRY(loadSection(Sec.emplace<AST::CustomSection>()) |
86 | 2.04M | .map_error(ReportError)); |
87 | 2.04M | break; |
88 | 2.04M | case 0x01: |
89 | 5.34k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::CoreModuleSection>()) |
90 | 5.19k | .map_error(ReportError)); |
91 | 5.19k | break; |
92 | 18.2k | case 0x02: |
93 | 18.2k | EXPECTED_TRY( |
94 | 17.8k | loadSection(Sec.emplace<AST::Component::CoreInstanceSection>()) |
95 | 17.8k | .map_error(ReportError)); |
96 | 17.8k | break; |
97 | 459k | case 0x03: |
98 | 459k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::CoreTypeSection>()) |
99 | 459k | .map_error(ReportError)); |
100 | 459k | break; |
101 | 459k | case 0x04: |
102 | 7.14k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::ComponentSection>()) |
103 | 5.93k | .map_error(ReportError)); |
104 | 5.93k | break; |
105 | 162k | case 0x05: |
106 | 162k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::InstanceSection>()) |
107 | 162k | .map_error(ReportError)); |
108 | 162k | break; |
109 | 162k | case 0x06: |
110 | 8.08k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::AliasSection>()) |
111 | 7.95k | .map_error(ReportError)); |
112 | 7.95k | break; |
113 | 1.84M | case 0x07: |
114 | 1.84M | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::TypeSection>()) |
115 | 1.84M | .map_error(ReportError)); |
116 | 1.84M | break; |
117 | 1.84M | case 0x08: |
118 | 33.7k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::CanonSection>()) |
119 | 33.0k | .map_error(ReportError)); |
120 | 33.0k | break; |
121 | 33.0k | case 0x09: |
122 | 1.67k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::StartSection>()) |
123 | 1.54k | .map_error(ReportError)); |
124 | 1.54k | break; |
125 | 22.2k | case 0x0A: |
126 | 22.2k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::ImportSection>()) |
127 | 22.0k | .map_error(ReportError)); |
128 | 22.0k | break; |
129 | 22.0k | case 0x0B: |
130 | 7.19k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::ExportSection>()) |
131 | 7.07k | .map_error(ReportError)); |
132 | 7.07k | break; |
133 | 7.07k | default: |
134 | 56 | return logLoadError(ErrCode::Value::MalformedSection, |
135 | 56 | FMgr.getLastOffset(), ASTNodeAttr::Component); |
136 | 4.61M | } |
137 | 4.61M | Offset = FMgr.getOffset(); |
138 | 4.61M | } |
139 | 10.3k | return {}; |
140 | 15.4k | } |
141 | | |
142 | | } // namespace Loader |
143 | | } // namespace WasmEdge |