srctree

Robin Lindén parent 4fb56100 7cf4eed3
wasm: Implement parsing the start section

inlinesplit
wasm/wasm.cpp added: 57, removed: 7, total 50
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2023-2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
@@ -34,6 +34,10 @@ std::optional<std::vector<T>> parse_vector(std::istream &&);
 
template<typename T>
std::optional<T> parse(std::istream &) = delete;
template<typename T>
std::optional<T> parse(std::istream &&is) {
return parse<T>(is);
}
 
template<>
std::optional<std::uint32_t> parse(std::istream &is) {
@@ -370,6 +374,19 @@ std::optional<ExportSection> Module::export_section() const {
return std::nullopt;
}
 
std::optional<StartSection> Module::start_section() const {
auto content = get_section_data(sections, SectionId::Start);
if (!content) {
return std::nullopt;
}
 
if (auto maybe_start = parse<FuncIdx>(std::stringstream(std::move(*content)))) {
return StartSection{.start = *maybe_start};
}
 
return std::nullopt;
}
 
std::optional<CodeSection> Module::code_section() const {
auto content = get_section_data(sections, SectionId::Code);
if (!content) {
 
wasm/wasm.h added: 57, removed: 7, total 50
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2023-2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
@@ -17,6 +17,7 @@ namespace wasm {
 
// https://webassembly.github.io/spec/core/binary/modules.html#indices
using TypeIdx = std::uint32_t;
using FuncIdx = std::uint32_t;
 
// https://webassembly.github.io/spec/core/binary/modules.html#sections
enum class SectionId {
@@ -136,6 +137,12 @@ struct ExportSection {
[[nodiscard]] bool operator==(ExportSection const &) const = default;
};
 
struct StartSection {
FuncIdx start{};
 
[[nodiscard]] bool operator==(StartSection const &) const = default;
};
 
// https://webassembly.github.io/spec/core/binary/modules.html#binary-codesec
struct CodeEntry {
struct Local {
@@ -179,7 +186,7 @@ struct Module {
// TODO(robinlinden): memory_section
// TODO(robinlinden): global_section
std::optional<ExportSection> export_section() const;
// TODO(robinlinden): start_section
std::optional<StartSection> start_section() const;
// TODO(robinlinden): element_section
std::optional<CodeSection> code_section() const;
// TODO(robinlinden): data_section
 
wasm/wasm_test.cpp added: 57, removed: 7, total 50
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023 Robin Lindén <dev@robinlinden.eu>
// SPDX-FileCopyrightText: 2023-2024 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
@@ -105,6 +105,31 @@ void export_section_tests() {
});
}
 
void start_section_tests() {
etest::test("start section, non-existent", [] {
auto module = wasm::Module{};
expect_eq(module.start_section(), std::nullopt);
});
 
etest::test("start section, missing start", [] {
auto module = wasm::Module{.sections{wasm::Section{
.id = wasm::SectionId::Start,
.content{},
}}};
 
expect_eq(module.start_section(), std::nullopt);
});
 
etest::test("start section, excellent", [] {
auto module = wasm::Module{.sections{wasm::Section{
.id = wasm::SectionId::Start,
.content{42},
}}};
 
expect_eq(module.start_section(), wasm::StartSection{.start = 42});
});
}
 
void function_section_tests() {
etest::test("function section, non-existent", [] {
auto module = wasm::Module{};
@@ -553,6 +578,7 @@ int main() {
function_section_tests();
table_section_tests();
export_section_tests();
start_section_tests();
code_section_tests();
 
return etest::run_all_tests();