Skip to content

Commit

Permalink
wasm: Simplify the parsed instruction format
Browse files Browse the repository at this point in the history
This reduces the memory usage of the instructions by a lot and
simplifies the code that works with them.
  • Loading branch information
robinlinden committed Jan 9, 2025
1 parent 1696c9f commit b27749a
Show file tree
Hide file tree
Showing 10 changed files with 168 additions and 186 deletions.
28 changes: 14 additions & 14 deletions wasm/byte_code_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,11 +661,13 @@ tl::expected<Module, ModuleParseError> ByteCodeParser::parse_module(std::istream
return module;
}

// NOLINTNEXTLINE(misc-no-recursion)
std::optional<std::vector<instructions::Instruction>> ByteCodeParser::parse_instructions(std::istream &is) {
using namespace instructions;
std::vector<Instruction> instructions{};

// If an End-opcode is encountered when nesting == 0, we're done.
int nesting = 0;

while (true) {
std::uint8_t opcode{};
if (!is.read(reinterpret_cast<char *>(&opcode), sizeof(opcode))) {
Expand All @@ -679,12 +681,8 @@ std::optional<std::vector<instructions::Instruction>> ByteCodeParser::parse_inst
return std::nullopt;
}

auto block_instructions = parse_instructions(is);
if (!block_instructions) {
return std::nullopt;
}

instructions.emplace_back(Block{*std::move(type), *std::move(block_instructions)});
instructions.emplace_back(Block{*std::move(type)});
++nesting;
break;
}
case Loop::kOpcode: {
Expand All @@ -693,12 +691,8 @@ std::optional<std::vector<instructions::Instruction>> ByteCodeParser::parse_inst
return std::nullopt;
}

auto block_instructions = parse_instructions(is);
if (!block_instructions) {
return std::nullopt;
}

instructions.emplace_back(Loop{*std::move(type), *std::move(block_instructions)});
instructions.emplace_back(Loop{*std::move(type)});
++nesting;
break;
}
case Branch::kOpcode: {
Expand All @@ -721,7 +715,13 @@ std::optional<std::vector<instructions::Instruction>> ByteCodeParser::parse_inst
instructions.emplace_back(Return{});
break;
case End::kOpcode:
return instructions;
instructions.emplace_back(End{});
if (nesting == 0) {
return instructions;
}

--nesting;
break;
case I32Const::kOpcode: {
auto value = wasm::Leb128<std::int32_t>::decode_from(is);
if (!value) {
Expand Down
16 changes: 9 additions & 7 deletions wasm/byte_code_parser_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ void global_section_tests(etest::Suite &s) {
a.expect_eq(module.global_section,
wasm::GlobalSection{.globals{{
.type{wasm::ValueType::Int32, wasm::GlobalType::Mutability::Const},
.init{wasm::instructions::I32Const{42}},
.init{wasm::instructions::I32Const{42}, wasm::instructions::End{}},
}}});
});

Expand All @@ -421,7 +421,7 @@ void global_section_tests(etest::Suite &s) {
a.expect_eq(module.global_section,
wasm::GlobalSection{.globals{{
.type{wasm::ValueType::Int32, wasm::GlobalType::Mutability::Var},
.init{wasm::instructions::I32Const{42}},
.init{wasm::instructions::I32Const{42}, wasm::instructions::End{}},
}}});
});

Expand All @@ -433,11 +433,11 @@ void global_section_tests(etest::Suite &s) {
wasm::GlobalSection{.globals{
{
.type{wasm::ValueType::Int32, wasm::GlobalType::Mutability::Var},
.init{wasm::instructions::I32Const{42}},
.init{wasm::instructions::I32Const{42}, wasm::instructions::End{}},
},
{
.type{wasm::ValueType::Int32, wasm::GlobalType::Mutability::Const},
.init{wasm::instructions::I32Const{42}},
.init{wasm::instructions::I32Const{42}, wasm::instructions::End{}},
},
}});
});
Expand Down Expand Up @@ -633,7 +633,9 @@ void code_section_tests(etest::Suite &s) {

wasm::CodeSection expected{.entries{
wasm::CodeEntry{
.code{wasm::instructions::I32Const{0b11}, wasm::instructions::I32PopulationCount{}},
.code{wasm::instructions::I32Const{0b11},
wasm::instructions::I32PopulationCount{},
wasm::instructions::End{}},
.locals{{1, wasm::ValueType::Int32}},
},
}};
Expand All @@ -647,11 +649,11 @@ void code_section_tests(etest::Suite &s) {

wasm::CodeSection expected{.entries{
wasm::CodeEntry{
.code{wasm::instructions::I32Const{42}},
.code{wasm::instructions::I32Const{42}, wasm::instructions::End{}},
.locals{{1, wasm::ValueType::Int32}},
},
wasm::CodeEntry{
.code{},
.code{wasm::instructions::End{}},
.locals{{5, wasm::ValueType::Int64}, {6, wasm::ValueType::Float32}},
},
}};
Expand Down
22 changes: 0 additions & 22 deletions wasm/instructions.cpp

This file was deleted.

7 changes: 2 additions & 5 deletions wasm/instructions.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include <cstdint>
#include <string_view>
#include <variant>
#include <vector>

namespace wasm::instructions {

Expand Down Expand Up @@ -140,16 +139,14 @@ struct Block {
static constexpr std::uint8_t kOpcode = 0x02;
static constexpr std::string_view kMnemonic = "block";
BlockType type{};
std::vector<Instruction> instructions;
[[nodiscard]] bool operator==(Block const &) const;
[[nodiscard]] bool operator==(Block const &) const = default;
};

struct Loop {
static constexpr std::uint8_t kOpcode = 0x03;
static constexpr std::string_view kMnemonic = "loop";
BlockType type{};
std::vector<Instruction> instructions;
[[nodiscard]] bool operator==(Loop const &) const;
[[nodiscard]] bool operator==(Loop const &) const = default;
};

struct Branch {
Expand Down
Loading

0 comments on commit b27749a

Please sign in to comment.