Coverage Report

Created: 2025-07-01 06:18

/src/WasmEdge/lib/loader/serialize/serial_section.cpp
Line
Count
Source (jump to first uncovered line)
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: 2019-2024 Second State INC
3
4
#include "loader/serialize.h"
5
6
namespace WasmEdge {
7
namespace Loader {
8
9
// Serialize custom section. See "include/loader/serialize.h".
10
Expect<void>
11
Serializer::serializeSection(const AST::CustomSection &Sec,
12
0
                             std::vector<uint8_t> &OutVec) const noexcept {
13
  // Custom section: 0x00 + size:u32 + name:vec(byte) + content:byte*.
14
  // Section ID.
15
0
  OutVec.push_back(0x00U);
16
0
  auto OrgSize = OutVec.size();
17
  // Name: vec(byte).
18
0
  serializeU32(static_cast<uint32_t>(Sec.getName().size()), OutVec);
19
0
  OutVec.insert(OutVec.end(), Sec.getName().begin(), Sec.getName().end());
20
  // Content: byte*.
21
0
  OutVec.insert(OutVec.end(), Sec.getContent().begin(), Sec.getContent().end());
22
  // Backward insert the section size.
23
0
  serializeU32(static_cast<uint32_t>(OutVec.size() - OrgSize), OutVec,
24
0
               std::next(OutVec.begin(), static_cast<ptrdiff_t>(OrgSize)));
25
0
  return {};
26
0
}
27
28
// Serialize type section. See "include/loader/serialize.h".
29
Expect<void>
30
Serializer::serializeSection(const AST::TypeSection &Sec,
31
0
                             std::vector<uint8_t> &OutVec) const noexcept {
32
  // Type section: 0x01 + size:u32 + content:vec(rectype).
33
0
  auto STypes = Sec.getContent();
34
35
  // record the recursive type vector size.
36
0
  if (STypes.size() > 0) {
37
    // Section ID.
38
0
    OutVec.push_back(0x01U);
39
0
    auto OrgSize = OutVec.size();
40
0
    uint32_t RecCnt = 0;
41
    // Content: vec(rectype).
42
0
    for (uint32_t I = 0; I < STypes.size(); I++) {
43
0
      auto RecInfo = STypes[I].getRecursiveInfo();
44
0
      if (!RecInfo.has_value()) {
45
0
        RecCnt++;
46
0
      } else if (RecInfo->Index == 0) {
47
        // First element of recursive type.
48
0
        if (!Conf.hasProposal(Proposal::GC)) {
49
0
          return logNeedProposal(ErrCode::Value::MalformedValType, Proposal::GC,
50
0
                                 ASTNodeAttr::Sec_Type);
51
0
        }
52
0
        OutVec.push_back(static_cast<uint8_t>(TypeCode::Rec));
53
0
        serializeU32(RecInfo->RecTypeSize, OutVec);
54
0
        RecCnt++;
55
0
      }
56
0
      EXPECTED_TRY(serializeType(STypes[I], OutVec).map_error([](auto E) {
57
0
        spdlog::error(ASTNodeAttr::Sec_Type);
58
0
        return E;
59
0
      }));
60
0
    }
61
    // Backward insert the recursive type vector size.
62
0
    serializeU32(RecCnt, OutVec,
63
0
                 std::next(OutVec.begin(), static_cast<ptrdiff_t>(OrgSize)));
64
    // Backward insert the section size.
65
0
    serializeU32(static_cast<uint32_t>(OutVec.size() - OrgSize), OutVec,
66
0
                 std::next(OutVec.begin(), static_cast<ptrdiff_t>(OrgSize)));
67
0
  }
68
0
  return {};
69
0
}
70
71
// Serialize import section. See "include/loader/serialize.h".
72
Expect<void>
73
Serializer::serializeSection(const AST::ImportSection &Sec,
74
0
                             std::vector<uint8_t> &OutVec) const noexcept {
75
  // Import section: 0x02 + size:u32 + content:vec(importdesc).
76
0
  return serializeSectionContent(
77
0
      Sec, 0x02U, OutVec,
78
0
      [=](const AST::ImportDesc &R, std::vector<uint8_t> &V) {
79
0
        return serializeDesc(R, V);
80
0
      });
81
0
}
82
83
// Serialize function section. See "include/loader/serialize.h".
84
Expect<void>
85
Serializer::serializeSection(const AST::FunctionSection &Sec,
86
0
                             std::vector<uint8_t> &OutVec) const noexcept {
87
  // Function section: 0x03 + size:u32 + content:vec(u32).
88
0
  return serializeSectionContent(
89
0
      Sec, 0x03U, OutVec,
90
0
      [=](const uint32_t &R, std::vector<uint8_t> &V) -> Expect<void> {
91
0
        serializeU32(R, V);
92
0
        return {};
93
0
      });
94
0
}
95
96
// Serialize table section. See "include/loader/serialize.h".
97
Expect<void>
98
Serializer::serializeSection(const AST::TableSection &Sec,
99
0
                             std::vector<uint8_t> &OutVec) const noexcept {
100
  // Table section: 0x04 + size:u32 + content:vec(tabletype).
101
0
  return serializeSectionContent(
102
0
      Sec, 0x04U, OutVec,
103
0
      [=](const AST::TableSegment &R, std::vector<uint8_t> &V) {
104
0
        return serializeSegment(R, V);
105
0
      });
106
0
}
107
108
// Serialize memory section. See "include/loader/serialize.h".
109
Expect<void>
110
Serializer::serializeSection(const AST::MemorySection &Sec,
111
0
                             std::vector<uint8_t> &OutVec) const noexcept {
112
  // Memory section: 0x05 + size:u32 + content:vec(memorytype).
113
0
  return serializeSectionContent(
114
0
      Sec, 0x05U, OutVec,
115
0
      [=](const AST::MemoryType &R, std::vector<uint8_t> &V) {
116
0
        return serializeType(R, V);
117
0
      });
118
0
}
119
120
// Serialize global section. See "include/loader/serialize.h".
121
Expect<void>
122
Serializer::serializeSection(const AST::GlobalSection &Sec,
123
0
                             std::vector<uint8_t> &OutVec) const noexcept {
124
  // Global section: 0x06 + size:u32 + content:vec(globaltype).
125
0
  return serializeSectionContent(
126
0
      Sec, 0x06U, OutVec,
127
0
      [=](const AST::GlobalSegment &R, std::vector<uint8_t> &V) {
128
0
        return serializeSegment(R, V);
129
0
      });
130
0
}
131
132
// Serialize export section. See "include/loader/serialize.h".
133
Expect<void>
134
Serializer::serializeSection(const AST::ExportSection &Sec,
135
0
                             std::vector<uint8_t> &OutVec) const noexcept {
136
  // Export section: 0x07 + size:u32 + content:vec(exportdesc).
137
0
  return serializeSectionContent(
138
0
      Sec, 0x07U, OutVec,
139
0
      [=](const AST::ExportDesc &R, std::vector<uint8_t> &V) {
140
0
        return serializeDesc(R, V);
141
0
      });
142
0
}
143
144
// Serialize start section. See "include/loader/serialize.h".
145
Expect<void>
146
Serializer::serializeSection(const AST::StartSection &Sec,
147
0
                             std::vector<uint8_t> &OutVec) const noexcept {
148
  // Start section: 0x08 + size:u32 + idx:u32.
149
0
  if (Sec.getContent()) {
150
    // Section ID.
151
0
    OutVec.push_back(0x08U);
152
0
    auto OrgSize = OutVec.size();
153
    // Idx: u32.
154
0
    serializeU32(*Sec.getContent(), OutVec);
155
    // Backward insert the section size.
156
0
    serializeU32(static_cast<uint32_t>(OutVec.size() - OrgSize), OutVec,
157
0
                 std::next(OutVec.begin(), static_cast<ptrdiff_t>(OrgSize)));
158
0
  }
159
0
  return {};
160
0
}
161
162
// Serialize element section. See "include/loader/serialize.h".
163
Expect<void>
164
Serializer::serializeSection(const AST::ElementSection &Sec,
165
0
                             std::vector<uint8_t> &OutVec) const noexcept {
166
  // Element section: 0x09 + size:u32 + content:vec(elemseg).
167
0
  return serializeSectionContent(
168
0
      Sec, 0x09U, OutVec,
169
0
      [=](const AST::ElementSegment &R, std::vector<uint8_t> &V) {
170
0
        return serializeSegment(R, V);
171
0
      });
172
0
}
173
174
// Serialize code section. See "include/loader/serialize.h".
175
Expect<void>
176
Serializer::serializeSection(const AST::CodeSection &Sec,
177
0
                             std::vector<uint8_t> &OutVec) const noexcept {
178
  // Code section: 0x0A + size:u32 + content:vec(codeseg).
179
0
  return serializeSectionContent(
180
0
      Sec, 0x0AU, OutVec,
181
0
      [=](const AST::CodeSegment &R, std::vector<uint8_t> &V) {
182
0
        return serializeSegment(R, V);
183
0
      });
184
0
}
185
186
// Serialize data section. See "include/loader/serialize.h".
187
Expect<void>
188
Serializer::serializeSection(const AST::DataSection &Sec,
189
0
                             std::vector<uint8_t> &OutVec) const noexcept {
190
  // Data section: 0x0B + size:u32 + content:vec(dataseg).
191
0
  return serializeSectionContent(
192
0
      Sec, 0x0BU, OutVec,
193
0
      [=](const AST::DataSegment &R, std::vector<uint8_t> &V) {
194
0
        return serializeSegment(R, V);
195
0
      });
196
0
}
197
198
// Serialize datacount section. See "include/loader/serialize.h".
199
Expect<void>
200
Serializer::serializeSection(const AST::DataCountSection &Sec,
201
0
                             std::vector<uint8_t> &OutVec) const noexcept {
202
  // Datacount section: 0x0C + size:u32 + idx:u32.
203
0
  if (Sec.getContent()) {
204
    // This section is for BulkMemoryOperations or ReferenceTypes proposal.
205
0
    if (!Conf.hasProposal(Proposal::BulkMemoryOperations) &&
206
0
        !Conf.hasProposal(Proposal::ReferenceTypes)) {
207
0
      return logNeedProposal(ErrCode::Value::MalformedSection,
208
0
                             Proposal::BulkMemoryOperations,
209
0
                             ASTNodeAttr::Sec_DataCount);
210
0
    }
211
    // Section ID.
212
0
    OutVec.push_back(0x0CU);
213
0
    auto OrgSize = OutVec.size();
214
    // Idx: u32.
215
0
    serializeU32(*Sec.getContent(), OutVec);
216
    // Backward insert the section size.
217
0
    serializeU32(static_cast<uint32_t>(OutVec.size() - OrgSize), OutVec,
218
0
                 std::next(OutVec.begin(), static_cast<ptrdiff_t>(OrgSize)));
219
0
  }
220
0
  return {};
221
0
}
222
223
// Serialize tag section. See "include/loader/serialize.h".
224
Expect<void>
225
Serializer::serializeSection(const AST::TagSection &Sec,
226
0
                             std::vector<uint8_t> &OutVec) const noexcept {
227
  // Tag section: 0x0D + size:u32 + content:vec(tag)
228
0
  return serializeSectionContent(
229
0
      Sec, 0x0DU, OutVec, [=](const AST::TagType &R, std::vector<uint8_t> &V) {
230
0
        return serializeType(R, V);
231
0
      });
232
0
}
233
234
} // namespace Loader
235
} // namespace WasmEdge