瀏覽代碼

LibWasm: Make the Module ctor generate a list of module functions

This list is supposed to be accessed rather frequently, so there's no
reason to make things slower by generating it many times on the spot.
Ali Mohammad Pur 4 年之前
父節點
當前提交
2b755f1fbf

+ 23 - 1
Userland/Libraries/LibWasm/Parser/Parser.cpp

@@ -970,7 +970,7 @@ ParseResult<Locals> Locals::parse(InputStream& stream)
     return Locals { static_cast<u32>(count), type.release_value() };
 }
 
-ParseResult<Func> Func::parse(InputStream& stream)
+ParseResult<CodeSection::Func> CodeSection::Func::parse(InputStream& stream)
 {
     ScopeLogger<WASM_BINPARSER_DEBUG> logger("Func");
     auto locals = parse_vector<Locals>(stream);
@@ -1227,6 +1227,28 @@ ParseResult<Module> Module::parse(InputStream& stream)
     return Module { move(sections) };
 }
 
+void Module::populate_sections()
+{
+    const FunctionSection* function_section { nullptr };
+    for_each_section_of_type<FunctionSection>([&](const FunctionSection& section) { function_section = &section; });
+    for_each_section_of_type<CodeSection>([&](const CodeSection& section) {
+        // FIXME: This should be considered invalid once validation is implemented.
+        if (!function_section)
+            return;
+        size_t index = 0;
+        for (auto& entry : section.functions()) {
+            auto& type_index = function_section->types()[index];
+            Vector<ValueType> locals;
+            for (auto& local : entry.func().locals()) {
+                for (size_t i = 0; i < local.n(); ++i)
+                    locals.append(local.type());
+            }
+            m_functions.empend(type_index, move(locals), entry.func().body());
+            ++index;
+        }
+    });
+}
+
 String parse_error_to_string(ParseError error)
 {
     switch (error) {

+ 1 - 1
Userland/Libraries/LibWasm/Printer/Printer.cpp

@@ -242,7 +242,7 @@ void Printer::print(const Wasm::Expression& expression)
         print(instr);
 }
 
-void Printer::print(const Wasm::Func& func)
+void Printer::print(const Wasm::CodeSection::Func& func)
 {
     print_indent();
     print("(function\n");

+ 3 - 2
Userland/Libraries/LibWasm/Printer/Printer.h

@@ -11,14 +11,16 @@
 namespace Wasm {
 
 struct Printer {
-    explicit Printer(OutputStream& stream)
+    explicit Printer(OutputStream& stream, size_t initial_indent = 0)
         : m_stream(stream)
+        , m_indent(initial_indent)
     {
     }
 
     void print(const Wasm::BlockType&);
     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&);
@@ -29,7 +31,6 @@ struct Printer {
     void print(const Wasm::ExportSection&);
     void print(const Wasm::ExportSection::Export&);
     void print(const Wasm::Expression&);
-    void print(const Wasm::Func&);
     void print(const Wasm::FunctionSection&);
     void print(const Wasm::FunctionType&);
     void print(const Wasm::GlobalSection&);

+ 41 - 20
Userland/Libraries/LibWasm/Types.h

@@ -799,27 +799,26 @@ private:
     ValueType m_type;
 };
 
-// https://webassembly.github.io/spec/core/bikeshed/#binary-func
-class Func {
+class CodeSection {
 public:
-    explicit Func(Vector<Locals> locals, Expression body)
-        : m_locals(move(locals))
-        , m_body(move(body))
-    {
-    }
-
-    auto& locals() const { return m_locals; }
-    auto& body() const { return m_body; }
+    // https://webassembly.github.io/spec/core/bikeshed/#binary-func
+    class Func {
+    public:
+        explicit Func(Vector<Locals> locals, Expression body)
+            : m_locals(move(locals))
+            , m_body(move(body))
+        {
+        }
 
-    static ParseResult<Func> parse(InputStream& stream);
+        auto& locals() const { return m_locals; }
+        auto& body() const { return m_body; }
 
-private:
-    Vector<Locals> m_locals;
-    Expression m_body;
-};
+        static ParseResult<Func> parse(InputStream& stream);
 
-class CodeSection {
-public:
+    private:
+        Vector<Locals> m_locals;
+        Expression m_body;
+    };
     class Code {
     public:
         explicit Code(u32 size, Func func)
@@ -916,10 +915,10 @@ class Module {
 public:
     class Function {
     public:
-        explicit Function(TypeIndex type, Vector<ValueType> local_types, Expression body)
+        explicit Function(TypeIndex type, Vector<ValueType> local_types, const Expression& body)
             : m_type(type)
             , m_local_types(move(local_types))
-            , m_body(move(body))
+            , m_body(body)
         {
         }
 
@@ -930,7 +929,7 @@ public:
     private:
         TypeIndex m_type;
         Vector<ValueType> m_local_types;
-        Expression m_body;
+        const Expression& m_body;
     };
 
     using AnySection = Variant<
@@ -954,13 +953,35 @@ public:
     explicit Module(Vector<AnySection> sections)
         : m_sections(move(sections))
     {
+        populate_sections();
     }
 
     auto& sections() const { return m_sections; }
+    auto& functions() const { return m_functions; }
+
+    template<typename T, typename Callback>
+    void for_each_section_of_type(Callback&& callback) const
+    {
+        for (auto& section : m_sections) {
+            if (auto ptr = section.get_pointer<T>())
+                callback(*ptr);
+        }
+    }
+    template<typename T, typename Callback>
+    void for_each_section_of_type(Callback&& callback)
+    {
+        for (auto& section : m_sections) {
+            if (auto ptr = section.get_pointer<T>())
+                callback(*ptr);
+        }
+    }
 
     static ParseResult<Module> parse(InputStream& stream);
 
 private:
+    void populate_sections();
+
     Vector<AnySection> m_sections;
+    Vector<Function> m_functions;
 };
 }