/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 | 36.3k | 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 | 36.3k | auto Magic = FMgr.readBytes(4); |
23 | 36.3k | if (!Magic) { |
24 | 98 | return logLoadError(Magic.error(), FMgr.getLastOffset(), |
25 | 98 | ASTNodeAttr::Module); |
26 | 98 | } |
27 | 36.2k | std::vector<Byte> WasmMagic = {0x00, 0x61, 0x73, 0x6D}; |
28 | 36.2k | if (*Magic != WasmMagic) { |
29 | 154 | auto M = *Magic; |
30 | 154 | spdlog::error("Might an invalid wasm file, magic expected, but got 0x{:X} " |
31 | 154 | "0x{:X} 0x{:X} 0x{:X}"sv, |
32 | 154 | M[0], M[1], M[2], M[3]); |
33 | 154 | return logLoadError(ErrCode::Value::MalformedMagic, FMgr.getLastOffset(), |
34 | 154 | ASTNodeAttr::Module); |
35 | 154 | } |
36 | 36.1k | auto Ver = FMgr.readBytes(4); |
37 | 36.1k | if (!Ver) { |
38 | 5 | return logLoadError(Ver.error(), FMgr.getLastOffset(), ASTNodeAttr::Module); |
39 | 5 | } |
40 | 36.1k | return std::make_pair(*Magic, *Ver); |
41 | 36.1k | } |
42 | | |
43 | | Expect<void> Loader::loadComponent(AST::Component::Component &Comp, |
44 | 14.9k | std::optional<uint64_t> Bound) { |
45 | 14.9k | ComponentNestGuard NestGuard(ComponentNestLevel); |
46 | 14.9k | if (unlikely(ComponentNestLevel > MaxComponentNestLevel)) { |
47 | 1 | return logLoadError(ErrCode::Value::ComponentNestLevelExceeded, |
48 | 1 | FMgr.getLastOffset(), ASTNodeAttr::Component); |
49 | 1 | } |
50 | 14.9k | auto ReportError = [](auto E) { |
51 | 6.15k | spdlog::error(ErrInfo::InfoAST(ASTNodeAttr::Component)); |
52 | 6.15k | return E; |
53 | 6.15k | }; |
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 | 14.9k | uint64_t StartOffset = FMgr.getOffset(); |
69 | 14.9k | uint64_t Offset = FMgr.getOffset(); |
70 | 14.9k | Expect<Byte> ResSecId; |
71 | | |
72 | 738k | while ((!Bound.has_value() || *Bound > Offset - StartOffset) && |
73 | 733k | (ResSecId = FMgr.readByte())) { |
74 | 730k | 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 | 730k | uint8_t NewSectionId = *ResSecId; |
80 | 730k | Comp.getSections().emplace_back(); |
81 | 730k | auto &Sec = Comp.getSections().back(); |
82 | | |
83 | 730k | switch (NewSectionId) { |
84 | 324k | case 0x00: |
85 | 324k | EXPECTED_TRY(loadSection(Sec.emplace<AST::CustomSection>()) |
86 | 324k | .map_error(ReportError)); |
87 | 324k | break; |
88 | 324k | case 0x01: |
89 | 3.15k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::CoreModuleSection>()) |
90 | 2.97k | .map_error(ReportError)); |
91 | 2.97k | break; |
92 | 4.35k | case 0x02: |
93 | 4.35k | EXPECTED_TRY( |
94 | 3.97k | loadSection(Sec.emplace<AST::Component::CoreInstanceSection>()) |
95 | 3.97k | .map_error(ReportError)); |
96 | 3.97k | break; |
97 | 62.0k | case 0x03: |
98 | 62.0k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::CoreTypeSection>()) |
99 | 61.4k | .map_error(ReportError)); |
100 | 61.4k | break; |
101 | 61.4k | case 0x04: |
102 | 7.18k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::ComponentSection>()) |
103 | 5.18k | .map_error(ReportError)); |
104 | 5.18k | break; |
105 | 14.0k | case 0x05: |
106 | 14.0k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::InstanceSection>()) |
107 | 13.7k | .map_error(ReportError)); |
108 | 13.7k | break; |
109 | 13.7k | case 0x06: |
110 | 1.97k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::AliasSection>()) |
111 | 1.82k | .map_error(ReportError)); |
112 | 1.82k | break; |
113 | 281k | case 0x07: |
114 | 281k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::TypeSection>()) |
115 | 280k | .map_error(ReportError)); |
116 | 280k | break; |
117 | 280k | case 0x08: |
118 | 12.5k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::CanonSection>()) |
119 | 11.8k | .map_error(ReportError)); |
120 | 11.8k | break; |
121 | 11.8k | case 0x09: |
122 | 943 | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::StartSection>()) |
123 | 810 | .map_error(ReportError)); |
124 | 810 | break; |
125 | 12.1k | case 0x0A: |
126 | 12.1k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::ImportSection>()) |
127 | 12.0k | .map_error(ReportError)); |
128 | 12.0k | break; |
129 | 12.0k | case 0x0B: |
130 | 5.24k | EXPECTED_TRY(loadSection(Sec.emplace<AST::Component::ExportSection>()) |
131 | 5.11k | .map_error(ReportError)); |
132 | 5.11k | break; |
133 | 5.11k | default: |
134 | 94 | return logLoadError(ErrCode::Value::MalformedSection, |
135 | 94 | FMgr.getLastOffset(), ASTNodeAttr::Component); |
136 | 730k | } |
137 | 724k | Offset = FMgr.getOffset(); |
138 | 724k | } |
139 | 8.69k | return {}; |
140 | 14.9k | } |
141 | | |
142 | | } // namespace Loader |
143 | | } // namespace WasmEdge |