Browse Source

LibWasm: Implement element section parsing

Diego 1 năm trước cách đây
mục cha
commit
f8ac883fb4
2 tập tin đã thay đổi với 47 bổ sung163 xóa
  1. 47 125
      Userland/Libraries/LibWasm/Parser/Parser.cpp
  2. 0 38
      Userland/Libraries/LibWasm/Types.h

+ 47 - 125
Userland/Libraries/LibWasm/Parser/Parser.cpp

@@ -1225,144 +1225,66 @@ ParseResult<StartSection> StartSection::parse(Stream& stream)
     return StartSection { result };
 }
 
-ParseResult<ElementSection::SegmentType0> ElementSection::SegmentType0::parse(Stream& stream)
-{
-    auto expression = TRY(Expression::parse(stream));
-    auto indices = TRY(parse_vector<GenericIndexParser<FunctionIndex>>(stream));
-
-    return SegmentType0 { indices, Active { 0, expression } };
-}
-
-ParseResult<ElementSection::SegmentType1> ElementSection::SegmentType1::parse(Stream& stream)
-{
-    auto kind_or_error = stream.read_value<u8>();
-    if (kind_or_error.is_error())
-        return with_eof_check(stream, ParseError::ExpectedKindTag);
-
-    auto kind = kind_or_error.release_value();
-    if (kind != 0)
-        return ParseError::InvalidTag;
-    auto indices = TRY(parse_vector<GenericIndexParser<FunctionIndex>>(stream));
-
-    return SegmentType1 { indices };
-}
-
-ParseResult<ElementSection::SegmentType2> ElementSection::SegmentType2::parse(Stream& stream)
-{
-    dbgln("Type 2");
-    (void)stream;
-    return ParseError::NotImplemented;
-}
-
-ParseResult<ElementSection::SegmentType3> ElementSection::SegmentType3::parse(Stream& stream)
-{
-    dbgln("Type 3");
-    (void)stream;
-    return ParseError::NotImplemented;
-}
-
-ParseResult<ElementSection::SegmentType4> ElementSection::SegmentType4::parse(Stream& stream)
-{
-    auto expression = TRY(Expression::parse(stream));
-    auto initializers = TRY(parse_vector<Expression>(stream));
-
-    return SegmentType4 {
-        .mode = Active {
-            .index = 0,
-            .expression = expression,
-        },
-        .initializer = initializers,
-    };
-}
-
-ParseResult<ElementSection::SegmentType5> ElementSection::SegmentType5::parse(Stream& stream)
-{
-    dbgln("Type 5");
-    (void)stream;
-    return ParseError::NotImplemented;
-}
-
-ParseResult<ElementSection::SegmentType6> ElementSection::SegmentType6::parse(Stream& stream)
-{
-    dbgln("Type 6");
-    (void)stream;
-    return ParseError::NotImplemented;
-}
-
-ParseResult<ElementSection::SegmentType7> ElementSection::SegmentType7::parse(Stream& stream)
-{
-    dbgln("Type 7");
-    (void)stream;
-    return ParseError::NotImplemented;
-}
-
 ParseResult<ElementSection::Element> ElementSection::Element::parse(Stream& stream)
 {
     ScopeLogger<WASM_BINPARSER_DEBUG> logger("Element"sv);
-    auto tag_or_error = stream.read_value<u8>();
+    auto tag_or_error = stream.read_value<LEB128<u32>>();
     if (tag_or_error.is_error())
         return with_eof_check(stream, ParseError::ExpectedKindTag);
 
     auto tag = tag_or_error.release_value();
 
-    switch (tag) {
-    case 0x00:
-        if (auto result = SegmentType0::parse(stream); result.is_error()) {
-            return result.error();
-        } else {
-            Vector<Instruction> instructions;
-            for (auto& index : result.value().function_indices)
-                instructions.empend(Instructions::ref_func, index);
-            return Element { ValueType(ValueType::FunctionReference), { Expression { move(instructions) } }, move(result.value().mode) };
-        }
-    case 0x01:
-        if (auto result = SegmentType1::parse(stream); result.is_error()) {
-            return result.error();
-        } else {
-            Vector<Instruction> instructions;
-            for (auto& index : result.value().function_indices)
-                instructions.empend(Instructions::ref_func, index);
-            return Element { ValueType(ValueType::FunctionReference), { Expression { move(instructions) } }, Passive {} };
-        }
-    case 0x02:
-        if (auto result = SegmentType2::parse(stream); result.is_error()) {
-            return result.error();
-        } else {
-            return ParseError::NotImplemented;
-        }
-    case 0x03:
-        if (auto result = SegmentType3::parse(stream); result.is_error()) {
-            return result.error();
-        } else {
-            return ParseError::NotImplemented;
-        }
-    case 0x04:
-        if (auto result = SegmentType4::parse(stream); result.is_error()) {
-            return result.error();
-        } else {
-            return Element { ValueType(ValueType::FunctionReference), move(result.value().initializer), move(result.value().mode) };
-        }
-    case 0x05:
-        if (auto result = SegmentType5::parse(stream); result.is_error()) {
-            return result.error();
-        } else {
-            return ParseError::NotImplemented;
-        }
-    case 0x06:
-        if (auto result = SegmentType6::parse(stream); result.is_error()) {
-            return result.error();
+    if (tag > 0x07)
+        return ParseError::InvalidTag;
+
+    auto has_passive = (tag & 0x01) != 0;
+    auto has_explicit_index = (tag & 0x02) != 0;
+    auto has_exprs = (tag & 0x04) != 0;
+
+    Variant<Active, Passive, Declarative> mode = Passive {};
+    if (has_passive) {
+        if (has_explicit_index) {
+            mode = Declarative {};
         } else {
-            return ParseError::NotImplemented;
+            mode = Passive {};
         }
-    case 0x07:
-        if (auto result = SegmentType7::parse(stream); result.is_error()) {
-            return result.error();
+    } else {
+        TableIndex table_index = 0;
+        if (has_explicit_index)
+            table_index = TRY(GenericIndexParser<TableIndex>::parse(stream));
+        auto expression = TRY(Expression::parse(stream));
+        mode = Active { table_index, expression };
+    }
+
+    auto type = ValueType(ValueType::FunctionReference);
+    if (has_passive || has_explicit_index) {
+        if (has_exprs) {
+            type = TRY(ValueType::parse(stream));
         } else {
-            return ParseError::NotImplemented;
+            auto extern_or_error = stream.read_value<u8>();
+            if (extern_or_error.is_error())
+                return with_eof_check(stream, ParseError::InvalidType);
+            // Make sure that this is a function, as it's technically only the
+            // allowed one.
+            if (extern_or_error.release_value() != 0x00) {
+                return ParseError::InvalidType;
+            }
+            type = ValueType(ValueType::FunctionReference);
         }
-    default:
-        return ParseError::InvalidTag;
     }
+
+    Vector<Expression> items;
+    if (!has_exprs) {
+        auto indices = TRY(parse_vector<GenericIndexParser<FunctionIndex>>(stream));
+        Vector<Instruction> instructions;
+        for (auto& index : indices)
+            instructions.empend(Instructions::ref_func, index);
+        items = { Expression { move(instructions) } };
+    } else {
+        items = TRY(parse_vector<Expression>(stream));
+    }
+
+    return Element { type, move(items), move(mode) };
 }
 
 ParseResult<ElementSection> ElementSection::parse(Stream& stream)

+ 0 - 38
Userland/Libraries/LibWasm/Types.h

@@ -797,44 +797,6 @@ public:
     struct Passive {
     };
 
-    struct SegmentType0 {
-        static ParseResult<SegmentType0> parse(Stream& stream);
-
-        Vector<FunctionIndex> function_indices;
-        Active mode;
-    };
-    struct SegmentType1 {
-        static ParseResult<SegmentType1> parse(Stream& stream);
-
-        Vector<FunctionIndex> function_indices;
-    };
-    struct SegmentType2 {
-        // FIXME: Implement me!
-        static ParseResult<SegmentType2> parse(Stream& stream);
-    };
-    struct SegmentType3 {
-        // FIXME: Implement me!
-        static ParseResult<SegmentType3> parse(Stream& stream);
-    };
-    struct SegmentType4 {
-        static ParseResult<SegmentType4> parse(Stream& stream);
-
-        Active mode;
-        Vector<Expression> initializer;
-    };
-    struct SegmentType5 {
-        // FIXME: Implement me!
-        static ParseResult<SegmentType5> parse(Stream& stream);
-    };
-    struct SegmentType6 {
-        // FIXME: Implement me!
-        static ParseResult<SegmentType6> parse(Stream& stream);
-    };
-    struct SegmentType7 {
-        // FIXME: Implement me!
-        static ParseResult<SegmentType7> parse(Stream& stream);
-    };
-
     struct Element {
         static ParseResult<Element> parse(Stream&);