Quellcode durchsuchen

LibWasm: Improve element validation and instantiation

Diego vor 1 Jahr
Ursprung
Commit
3225e6fad2

+ 6 - 3
Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp

@@ -275,7 +275,7 @@ InstantiationResult AbstractMachine::instantiate(Module const& module, Vector<Ex
                         return IterationDecision::Continue;
                     }
                     // FIXME: type-check the reference.
-                    references.prepend(reference.release_value());
+                    references.append(reference.release_value());
                 }
             }
             elements.append(move(references));
@@ -296,8 +296,12 @@ InstantiationResult AbstractMachine::instantiate(Module const& module, Vector<Ex
             auto current_index = index;
             ++index;
             auto active_ptr = segment.mode.get_pointer<ElementSection::Active>();
-            if (!active_ptr)
+            auto elem_instance = m_store.get(main_module_instance.elements()[current_index]);
+            if (!active_ptr) {
+                if (segment.mode.has<ElementSection::Declarative>())
+                    *elem_instance = ElementInstance(elem_instance->type(), {});
                 continue;
+            }
             Configuration config { m_store };
             if (m_should_limit_instruction_count)
                 config.enable_instruction_count_limit();
@@ -322,7 +326,6 @@ InstantiationResult AbstractMachine::instantiate(Module const& module, Vector<Ex
                 instantiation_result = InstantiationError { "Invalid element referenced by active element segment" };
                 return IterationDecision::Break;
             }
-            auto elem_instance = m_store.get(main_module_instance.elements()[current_index]);
             if (!table_instance || !elem_instance) {
                 instantiation_result = InstantiationError { "Invalid element referenced by active element segment" };
                 return IterationDecision::Break;

+ 3 - 0
Userland/Libraries/LibWasm/AbstractMachine/Validator.cpp

@@ -224,6 +224,9 @@ ErrorOr<void, ValidationError> Validator::validate(ElementSection const& section
             [](ElementSection::Passive const&) -> ErrorOr<void, ValidationError> { return {}; },
             [&](ElementSection::Active const& active) -> ErrorOr<void, ValidationError> {
                 TRY(validate(active.index));
+                auto table = m_context.tables[active.index.value()];
+                if (table.element_type() != segment.type)
+                    return Errors::invalid("active element reference type"sv);
                 auto expression_result = TRY(validate(active.expression, { ValueType(ValueType::I32) }));
                 if (!expression_result.is_constant)
                     return Errors::invalid("active element initializer"sv);

+ 4 - 4
Userland/Libraries/LibWasm/Parser/Parser.cpp

@@ -1281,10 +1281,10 @@ ParseResult<ElementSection::Element> ElementSection::Element::parse(Stream& stre
     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) } };
+        for (auto& index : indices) {
+            Vector<Instruction> instructions { Instruction(Instructions::ref_func, index) };
+            items.empend(move(instructions));
+        }
     } else {
         items = TRY(parse_vector<Expression>(stream));
     }