From a5194274afcd626557f9e0658da2ddc57b22d837 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Sat, 1 May 2021 22:49:17 +0430 Subject: LibWasm: Stub out/implement parsing of all ElementSection segments Previously, this was parsing only one kind because I mistakenly assumed that they all had the same shape, now it can parse two kinds, and will return NotImplemented for the rest. --- .../LibWasm/AbstractMachine/AbstractMachine.cpp | 29 +---- Userland/Libraries/LibWasm/Parser/Parser.cpp | 141 +++++++++++++++++++-- Userland/Libraries/LibWasm/Printer/Printer.cpp | 56 +++++--- Userland/Libraries/LibWasm/Printer/Printer.h | 12 +- Userland/Libraries/LibWasm/Types.h | 80 +++++++++--- 5 files changed, 236 insertions(+), 82 deletions(-) (limited to 'Userland') diff --git a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp index c22d60d379..c3612f532f 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp +++ b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp @@ -91,7 +91,7 @@ InstantiationResult AbstractMachine::instantiate(const Module& module, Vector global_values; ModuleInstance auxiliary_instance; @@ -125,29 +125,10 @@ InstantiationResult AbstractMachine::instantiate(const Module& module, Vector([&](const ElementSection& element_section) { - auto frame = make( - m_module_instance, - Vector {}, - element_section.function().offset(), - 1); - Configuration config { m_store }; - config.set_frame(move(frame)); - auto result = config.execute(); - // What if this traps? - VERIFY(!result.is_trap()); - size_t offset = 0; - result.values().first().value().visit( - [&](const auto& value) { offset = value; }, - [&](const FunctionAddress&) { VERIFY_NOT_REACHED(); }, - [&](const ExternAddress&) { VERIFY_NOT_REACHED(); }); - // FIXME: Module::get(*Index) - auto table_address = m_module_instance.tables().at(element_section.function().table().value()); - if (auto table_instance = m_store.get(table_address)) { - auto& init = element_section.function().init(); - for (size_t i = 0; i < init.size(); ++i) - table_instance->elements()[offset + i] = Reference { Reference::Func { init[i].value() } }; // HACK! - } + module.for_each_section_of_type([&](const ElementSection&) { + // FIXME: Implement me + // https://webassembly.github.io/spec/core/bikeshed/#element-segments%E2%91%A0 + // https://webassembly.github.io/spec/core/bikeshed/#instantiation%E2%91%A1 step 9 }); module.for_each_section_of_type([&](const DataSection& data_section) { diff --git a/Userland/Libraries/LibWasm/Parser/Parser.cpp b/Userland/Libraries/LibWasm/Parser/Parser.cpp index 8243c4ae01..81226e065d 100644 --- a/Userland/Libraries/LibWasm/Parser/Parser.cpp +++ b/Userland/Libraries/LibWasm/Parser/Parser.cpp @@ -931,26 +931,141 @@ ParseResult StartSection::parse(InputStream& stream) return StartSection { result.release_value() }; } -ParseResult ElementSection::Element::parse(InputStream& stream) +ParseResult ElementSection::SegmentType0::parse(InputStream& stream) +{ + auto expression = Expression::parse(stream); + if (expression.is_error()) + return expression.error(); + auto indices = parse_vector>(stream); + if (indices.is_error()) + return indices.error(); + + return SegmentType0 { ValueType(ValueType::FunctionReference), indices.release_value(), Active { 0, expression.release_value() } }; +} + +ParseResult ElementSection::SegmentType1::parse(InputStream& stream) +{ + u8 kind; + stream >> kind; + if (stream.has_any_error()) + return with_eof_check(stream, ParseError::ExpectedKindTag); + if (kind != 0) + return ParseError::InvalidTag; + auto indices = parse_vector>(stream); + if (indices.is_error()) + return indices.error(); + + return SegmentType1 { ValueType(ValueType::FunctionReference), indices.release_value() }; +} + +ParseResult ElementSection::SegmentType2::parse(InputStream& stream) +{ + dbgln("Type 2"); + (void)stream; + return ParseError::NotImplemented; +} + +ParseResult ElementSection::SegmentType3::parse(InputStream& stream) +{ + dbgln("Type 3"); + (void)stream; + return ParseError::NotImplemented; +} + +ParseResult ElementSection::SegmentType4::parse(InputStream& stream) +{ + dbgln("Type 4"); + (void)stream; + return ParseError::NotImplemented; +} + +ParseResult ElementSection::SegmentType5::parse(InputStream& stream) +{ + dbgln("Type 5"); + (void)stream; + return ParseError::NotImplemented; +} + +ParseResult ElementSection::SegmentType6::parse(InputStream& stream) +{ + dbgln("Type 6"); + (void)stream; + return ParseError::NotImplemented; +} + +ParseResult ElementSection::SegmentType7::parse(InputStream& stream) +{ + dbgln("Type 7"); + (void)stream; + return ParseError::NotImplemented; +} + +ParseResult ElementSection::Element::parse(InputStream& stream) { ScopeLogger logger("Element"); - auto table_index = GenericIndexParser::parse(stream); - if (table_index.is_error()) - return table_index.error(); - auto offset = Expression::parse(stream); - if (offset.is_error()) - return offset.error(); - auto init = parse_vector>(stream); - if (init.is_error()) - return init.error(); - - return Element { table_index.release_value(), offset.release_value(), init.release_value() }; + u8 tag; + stream >> tag; + if (stream.has_any_error()) + return with_eof_check(stream, ParseError::ExpectedKindTag); + + switch (tag) { + case 0x00: + if (auto result = SegmentType0::parse(stream); result.is_error()) { + return result.error(); + } else { + return AnyElementType { result.release_value() }; + } + case 0x01: + if (auto result = SegmentType1::parse(stream); result.is_error()) { + return result.error(); + } else { + return AnyElementType { result.release_value() }; + } + case 0x02: + if (auto result = SegmentType2::parse(stream); result.is_error()) { + return result.error(); + } else { + return AnyElementType { result.release_value() }; + } + case 0x03: + if (auto result = SegmentType3::parse(stream); result.is_error()) { + return result.error(); + } else { + return AnyElementType { result.release_value() }; + } + case 0x04: + if (auto result = SegmentType4::parse(stream); result.is_error()) { + return result.error(); + } else { + return AnyElementType { result.release_value() }; + } + case 0x05: + if (auto result = SegmentType5::parse(stream); result.is_error()) { + return result.error(); + } else { + return AnyElementType { result.release_value() }; + } + case 0x06: + if (auto result = SegmentType6::parse(stream); result.is_error()) { + return result.error(); + } else { + return AnyElementType { result.release_value() }; + } + case 0x07: + if (auto result = SegmentType7::parse(stream); result.is_error()) { + return result.error(); + } else { + return AnyElementType { result.release_value() }; + } + default: + return ParseError::InvalidTag; + } } ParseResult ElementSection::parse(InputStream& stream) { ScopeLogger logger("ElementSection"); - auto result = Element::parse(stream); + auto result = parse_vector(stream); if (result.is_error()) return result.error(); return ElementSection { result.release_value() }; diff --git a/Userland/Libraries/LibWasm/Printer/Printer.cpp b/Userland/Libraries/LibWasm/Printer/Printer.cpp index 17cf67a7fe..f02ac20103 100644 --- a/Userland/Libraries/LibWasm/Printer/Printer.cpp +++ b/Userland/Libraries/LibWasm/Printer/Printer.cpp @@ -169,42 +169,56 @@ void Printer::print(const Wasm::ElementSection& section) print("(section element\n"); { TemporaryChange change { m_indent, m_indent + 1 }; - print(section.function()); + for (auto& entry : section.segments()) + entry.visit([this](auto& segment) { print(segment); }); } print_indent(); print(")\n"); } -void Printer::print(const Wasm::ElementSection::Element& element) +void Printer::print(const Wasm::ElementSection::SegmentType0&) +{ +} + +void Printer::print(const Wasm::ElementSection::SegmentType1& segment) { print_indent(); - print("(element\n"); + print("(element segment kind 1\n"); { TemporaryChange change { m_indent, m_indent + 1 }; - print_indent(); - print("(table with index {})\n", element.table().value()); - print_indent(); - print("(offset\n"); - { - TemporaryChange change { m_indent, m_indent + 1 }; - print(element.offset()); - } - print_indent(); - print(")\n"); - print_indent(); - print("(initializers\n"); - { - TemporaryChange change { m_indent, m_indent + 1 }; - for (auto& index : element.init()) - print("(init function {})\n", index.value()); + for (auto& index : segment.function_indices) { + print_indent(); + print("(function index {})\n", index.value()); } - print_indent(); - print(")\n"); } print_indent(); print(")\n"); } +void Printer::print(const Wasm::ElementSection::SegmentType2&) +{ +} + +void Printer::print(const Wasm::ElementSection::SegmentType3&) +{ +} + +void Printer::print(const Wasm::ElementSection::SegmentType4&) +{ +} + +void Printer::print(const Wasm::ElementSection::SegmentType5&) +{ +} + +void Printer::print(const Wasm::ElementSection::SegmentType6&) +{ +} + +void Printer::print(const Wasm::ElementSection::SegmentType7&) +{ +} + void Printer::print(const Wasm::ExportSection& section) { print_indent(); diff --git a/Userland/Libraries/LibWasm/Printer/Printer.h b/Userland/Libraries/LibWasm/Printer/Printer.h index 8226916aa5..d1104c5ae6 100644 --- a/Userland/Libraries/LibWasm/Printer/Printer.h +++ b/Userland/Libraries/LibWasm/Printer/Printer.h @@ -21,13 +21,19 @@ struct Printer { void print(const Wasm::CodeSection&); void print(const Wasm::CodeSection::Code&); void print(const Wasm::CodeSection::Func&); - void print(const Wasm::ConstrainedStream&); void print(const Wasm::CustomSection&); void print(const Wasm::DataCountSection&); void print(const Wasm::DataSection&); void print(const Wasm::DataSection::Data&); void print(const Wasm::ElementSection&); - void print(const Wasm::ElementSection::Element&); + void print(const Wasm::ElementSection::SegmentType0&); + void print(const Wasm::ElementSection::SegmentType1&); + void print(const Wasm::ElementSection::SegmentType2&); + void print(const Wasm::ElementSection::SegmentType3&); + void print(const Wasm::ElementSection::SegmentType4&); + void print(const Wasm::ElementSection::SegmentType5&); + void print(const Wasm::ElementSection::SegmentType6&); + void print(const Wasm::ElementSection::SegmentType7&); void print(const Wasm::ExportSection&); void print(const Wasm::ExportSection::Export&); void print(const Wasm::Expression&); @@ -46,8 +52,6 @@ struct Printer { void print(const Wasm::MemoryType&); void print(const Wasm::Module&); void print(const Wasm::Module::Function&); - void print(const Wasm::ReconsumableStream&); - void print(const Wasm::ResultType&); void print(const Wasm::StartSection&); void print(const Wasm::StartSection::StartFunction&); void print(const Wasm::TableSection&); diff --git a/Userland/Libraries/LibWasm/Types.h b/Userland/Libraries/LibWasm/Types.h index 3fea1975da..4b834d7465 100644 --- a/Userland/Libraries/LibWasm/Types.h +++ b/Userland/Libraries/LibWasm/Types.h @@ -744,40 +744,80 @@ private: class ElementSection { public: - class Element { - public: - explicit Element(TableIndex table, Expression expr, Vector init) - : m_table(table) - , m_offset(move(expr)) - , m_init(move(init)) - { - } + struct Active { + TableIndex index; + Expression expression; + }; + struct Declarative { + }; + struct Passive { + }; - auto& table() const { return m_table; } - auto& offset() const { return m_offset; } - auto& init() const { return m_init; } + struct SegmentType0 { + // FIXME: Implement me! + static ParseResult parse(InputStream& stream); - static ParseResult parse(InputStream& stream); + ValueType type; + Vector function_indices; + Active mode; + }; + struct SegmentType1 { + static ParseResult parse(InputStream& stream); + ValueType type; + Vector function_indices; + }; + struct SegmentType2 { + // FIXME: Implement me! + static ParseResult parse(InputStream& stream); + }; + struct SegmentType3 { + // FIXME: Implement me! + static ParseResult parse(InputStream& stream); + }; + struct SegmentType4 { + // FIXME: Implement me! + static ParseResult parse(InputStream& stream); + }; + struct SegmentType5 { + // FIXME: Implement me! + static ParseResult parse(InputStream& stream); + }; + struct SegmentType6 { + // FIXME: Implement me! + static ParseResult parse(InputStream& stream); + }; + struct SegmentType7 { + // FIXME: Implement me! + static ParseResult parse(InputStream& stream); + }; - private: - TableIndex m_table; - Expression m_offset; - Vector m_init; + using AnyElementType = Variant< + SegmentType0, + SegmentType1, + SegmentType2, + SegmentType3, + SegmentType4, + SegmentType5, + SegmentType6, + SegmentType7>; + + struct Element { + static ParseResult parse(InputStream&); }; static constexpr u8 section_id = 9; - explicit ElementSection(Element func) - : m_function(move(func)) + explicit ElementSection(Vector segs) + : m_segments(move(segs)) { } - auto& function() const { return m_function; } + auto& segments() const { return m_segments; } static ParseResult parse(InputStream& stream); private: - Element m_function; + Vector m_segments; }; class Locals { -- cgit v1.2.3