summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp29
-rw-r--r--Userland/Libraries/LibWasm/Parser/Parser.cpp141
-rw-r--r--Userland/Libraries/LibWasm/Printer/Printer.cpp56
-rw-r--r--Userland/Libraries/LibWasm/Printer/Printer.h12
-rw-r--r--Userland/Libraries/LibWasm/Types.h80
5 files changed, 236 insertions, 82 deletions
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<Ex
m_module_instance.types() = section.types();
});
- // TODO: Validate stuff
+ // FIXME: Validate stuff
Vector<Value> global_values;
ModuleInstance auxiliary_instance;
@@ -125,29 +125,10 @@ InstantiationResult AbstractMachine::instantiate(const Module& module, Vector<Ex
return result.error();
}
- module.for_each_section_of_type<ElementSection>([&](const ElementSection& element_section) {
- auto frame = make<Frame>(
- m_module_instance,
- Vector<Value> {},
- 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<ElementSection>([&](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<DataSection>([&](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> StartSection::parse(InputStream& stream)
return StartSection { result.release_value() };
}
-ParseResult<ElementSection::Element> ElementSection::Element::parse(InputStream& stream)
+ParseResult<ElementSection::SegmentType0> ElementSection::SegmentType0::parse(InputStream& stream)
+{
+ auto expression = Expression::parse(stream);
+ if (expression.is_error())
+ return expression.error();
+ auto indices = parse_vector<GenericIndexParser<FunctionIndex>>(stream);
+ if (indices.is_error())
+ return indices.error();
+
+ return SegmentType0 { ValueType(ValueType::FunctionReference), indices.release_value(), Active { 0, expression.release_value() } };
+}
+
+ParseResult<ElementSection::SegmentType1> 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<GenericIndexParser<FunctionIndex>>(stream);
+ if (indices.is_error())
+ return indices.error();
+
+ return SegmentType1 { ValueType(ValueType::FunctionReference), indices.release_value() };
+}
+
+ParseResult<ElementSection::SegmentType2> ElementSection::SegmentType2::parse(InputStream& stream)
+{
+ dbgln("Type 2");
+ (void)stream;
+ return ParseError::NotImplemented;
+}
+
+ParseResult<ElementSection::SegmentType3> ElementSection::SegmentType3::parse(InputStream& stream)
+{
+ dbgln("Type 3");
+ (void)stream;
+ return ParseError::NotImplemented;
+}
+
+ParseResult<ElementSection::SegmentType4> ElementSection::SegmentType4::parse(InputStream& stream)
+{
+ dbgln("Type 4");
+ (void)stream;
+ return ParseError::NotImplemented;
+}
+
+ParseResult<ElementSection::SegmentType5> ElementSection::SegmentType5::parse(InputStream& stream)
+{
+ dbgln("Type 5");
+ (void)stream;
+ return ParseError::NotImplemented;
+}
+
+ParseResult<ElementSection::SegmentType6> ElementSection::SegmentType6::parse(InputStream& stream)
+{
+ dbgln("Type 6");
+ (void)stream;
+ return ParseError::NotImplemented;
+}
+
+ParseResult<ElementSection::SegmentType7> ElementSection::SegmentType7::parse(InputStream& stream)
+{
+ dbgln("Type 7");
+ (void)stream;
+ return ParseError::NotImplemented;
+}
+
+ParseResult<ElementSection::AnyElementType> ElementSection::Element::parse(InputStream& stream)
{
ScopeLogger<WASM_BINPARSER_DEBUG> logger("Element");
- auto table_index = GenericIndexParser<TableIndex>::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<GenericIndexParser<FunctionIndex>>(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> ElementSection::parse(InputStream& stream)
{
ScopeLogger<WASM_BINPARSER_DEBUG> logger("ElementSection");
- auto result = Element::parse(stream);
+ auto result = parse_vector<Element>(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<FunctionIndex> 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<SegmentType0> parse(InputStream& stream);
- static ParseResult<Element> parse(InputStream& stream);
+ ValueType type;
+ Vector<FunctionIndex> function_indices;
+ Active mode;
+ };
+ struct SegmentType1 {
+ static ParseResult<SegmentType1> parse(InputStream& stream);
+ ValueType type;
+ Vector<FunctionIndex> function_indices;
+ };
+ struct SegmentType2 {
+ // FIXME: Implement me!
+ static ParseResult<SegmentType2> parse(InputStream& stream);
+ };
+ struct SegmentType3 {
+ // FIXME: Implement me!
+ static ParseResult<SegmentType3> parse(InputStream& stream);
+ };
+ struct SegmentType4 {
+ // FIXME: Implement me!
+ static ParseResult<SegmentType4> parse(InputStream& stream);
+ };
+ struct SegmentType5 {
+ // FIXME: Implement me!
+ static ParseResult<SegmentType5> parse(InputStream& stream);
+ };
+ struct SegmentType6 {
+ // FIXME: Implement me!
+ static ParseResult<SegmentType6> parse(InputStream& stream);
+ };
+ struct SegmentType7 {
+ // FIXME: Implement me!
+ static ParseResult<SegmentType7> parse(InputStream& stream);
+ };
- private:
- TableIndex m_table;
- Expression m_offset;
- Vector<FunctionIndex> m_init;
+ using AnyElementType = Variant<
+ SegmentType0,
+ SegmentType1,
+ SegmentType2,
+ SegmentType3,
+ SegmentType4,
+ SegmentType5,
+ SegmentType6,
+ SegmentType7>;
+
+ struct Element {
+ static ParseResult<AnyElementType> parse(InputStream&);
};
static constexpr u8 section_id = 9;
- explicit ElementSection(Element func)
- : m_function(move(func))
+ explicit ElementSection(Vector<AnyElementType> segs)
+ : m_segments(move(segs))
{
}
- auto& function() const { return m_function; }
+ auto& segments() const { return m_segments; }
static ParseResult<ElementSection> parse(InputStream& stream);
private:
- Element m_function;
+ Vector<AnyElementType> m_segments;
};
class Locals {