diff --git a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp index 34bce7aa5d6..4e4a712c61a 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp +++ b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp @@ -14,14 +14,14 @@ namespace Wasm { -Optional Store::allocate(ModuleInstance& module, Module::Function const& function) +Optional Store::allocate(ModuleInstance& module, CodeSection::Code const& code, TypeIndex type_index) { FunctionAddress address { m_functions.size() }; - if (function.type().value() > module.types().size()) + if (type_index.value() > module.types().size()) return {}; - auto& type = module.types()[function.type().value()]; - m_functions.empend(WasmFunction { type, module, function }); + auto& type = module.types()[type_index.value()]; + m_functions.empend(WasmFunction { type, module, code }); return address; } @@ -223,15 +223,24 @@ InstantiationResult AbstractMachine::instantiate(Module const& module, Vector module_functions; - module_functions.ensure_capacity(module.functions().size()); + FunctionSection const* function_section { nullptr }; + module.for_each_section_of_type([&](FunctionSection const& section) { function_section = §ion; }); - for (auto& func : module.functions()) { - auto address = m_store.allocate(main_module_instance, func); - VERIFY(address.has_value()); - auxiliary_instance.functions().append(*address); - module_functions.append(*address); - } + Vector module_functions; + if (function_section) + module_functions.ensure_capacity(function_section->types().size()); + + module.for_each_section_of_type([&](auto& code_section) { + size_t i = 0; + for (auto& code : code_section.functions()) { + auto type_index = function_section->types()[i]; + auto address = m_store.allocate(main_module_instance, code, type_index); + VERIFY(address.has_value()); + auxiliary_instance.functions().append(*address); + module_functions.append(*address); + ++i; + } + }); BytecodeInterpreter interpreter(m_stack_info); diff --git a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h index a485c9f737e..5f26593057d 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h +++ b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h @@ -329,7 +329,7 @@ private: class WasmFunction { public: - explicit WasmFunction(FunctionType const& type, ModuleInstance const& module, Module::Function const& code) + explicit WasmFunction(FunctionType const& type, ModuleInstance const& module, CodeSection::Code const& code) : m_type(type) , m_module(module) , m_code(code) @@ -343,7 +343,7 @@ public: private: FunctionType m_type; ModuleInstance const& m_module; - Module::Function const& m_code; + CodeSection::Code const& m_code; }; class HostFunction { @@ -537,7 +537,7 @@ class Store { public: Store() = default; - Optional allocate(ModuleInstance& module, Module::Function const& function); + Optional allocate(ModuleInstance&, CodeSection::Code const&, TypeIndex); Optional allocate(HostFunction&&); Optional allocate(TableType const&); Optional allocate(MemoryType const&); diff --git a/Userland/Libraries/LibWasm/AbstractMachine/Configuration.cpp b/Userland/Libraries/LibWasm/AbstractMachine/Configuration.cpp index 79b513ddad7..c3d9cf39bf3 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/Configuration.cpp +++ b/Userland/Libraries/LibWasm/AbstractMachine/Configuration.cpp @@ -44,14 +44,16 @@ Result Configuration::call(Interpreter& interpreter, FunctionAddress address, Ve return Trap {}; if (auto* wasm_function = function->get_pointer()) { Vector locals = move(arguments); - locals.ensure_capacity(locals.size() + wasm_function->code().locals().size()); - for (auto& type : wasm_function->code().locals()) - locals.empend(type, 0ull); + locals.ensure_capacity(locals.size() + wasm_function->code().func().locals().size()); + for (auto& local : wasm_function->code().func().locals()) { + for (size_t i = 0; i < local.n(); ++i) + locals.empend(local.type(), 0ull); + } set_frame(Frame { wasm_function->module(), move(locals), - wasm_function->code().body(), + wasm_function->code().func().body(), wasm_function->type().results().size(), }); m_ip = 0; diff --git a/Userland/Libraries/LibWasm/AbstractMachine/Validator.cpp b/Userland/Libraries/LibWasm/AbstractMachine/Validator.cpp index 9c4d9bab444..57ac2476f4c 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/Validator.cpp +++ b/Userland/Libraries/LibWasm/AbstractMachine/Validator.cpp @@ -74,9 +74,13 @@ ErrorOr Validator::validate(Module& module) return result; } - module.for_each_section_of_type([this, &result](FunctionSection const& section) { - if (result.is_error()) + CodeSection const* code_section { nullptr }; + module.for_each_section_of_type([&](auto& section) { code_section = §ion; }); + module.for_each_section_of_type([&](FunctionSection const& section) { + if ((!code_section && !section.types().is_empty()) || (code_section && code_section->functions().size() != section.types().size())) { + result = Errors::invalid("FunctionSection"sv); return; + } m_context.functions.ensure_capacity(section.types().size() + m_context.functions.size()); for (auto& index : section.types()) { if (m_context.types.size() > index.value()) { diff --git a/Userland/Libraries/LibWasm/Parser/Parser.cpp b/Userland/Libraries/LibWasm/Parser/Parser.cpp index 7f4223975f6..6397387f1e4 100644 --- a/Userland/Libraries/LibWasm/Parser/Parser.cpp +++ b/Userland/Libraries/LibWasm/Parser/Parser.cpp @@ -1403,42 +1403,6 @@ ParseResult Module::parse(Stream& stream) return Module { move(sections) }; } -bool Module::populate_sections() -{ - auto is_ok = true; - FunctionSection const* function_section { nullptr }; - bool seen_code_section = false; - for_each_section_of_type([&](FunctionSection const& section) { function_section = §ion; }); - for_each_section_of_type([&](CodeSection const& section) { - if (!function_section && section.functions().is_empty()) { - return; - } - if (!function_section || function_section->types().size() != section.functions().size()) { - is_ok = false; - return; - } - seen_code_section = true; - size_t index = 0; - for (auto& entry : section.functions()) { - if (function_section->types().size() <= index) { - is_ok = false; - return; - } - auto& type_index = function_section->types()[index]; - Vector 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; - } - }); - if (!seen_code_section && function_section && !function_section->types().is_empty()) - return false; - return is_ok; -} - ByteString parse_error_to_byte_string(ParseError error) { switch (error) { diff --git a/Userland/Libraries/LibWasm/Printer/Printer.cpp b/Userland/Libraries/LibWasm/Printer/Printer.cpp index 28d6571bcef..3584fa6368f 100644 --- a/Userland/Libraries/LibWasm/Printer/Printer.cpp +++ b/Userland/Libraries/LibWasm/Printer/Printer.cpp @@ -541,33 +541,6 @@ void Printer::print(Wasm::Module const& module) print(")\n"); } -void Printer::print(Wasm::Module::Function const& func) -{ - print_indent(); - print("(function\n"); - { - TemporaryChange change { m_indent, m_indent + 1 }; - { - print_indent(); - print("(locals\n"); - { - TemporaryChange change { m_indent, m_indent + 1 }; - for (auto& locals : func.locals()) - print(locals); - } - print_indent(); - print(")\n"); - } - print_indent(); - print("(body\n"); - print(func.body()); - print_indent(); - print(")\n"); - } - print_indent(); - print(")\n"); -} - void Printer::print(Wasm::StartSection const& section) { print_indent(); diff --git a/Userland/Libraries/LibWasm/Printer/Printer.h b/Userland/Libraries/LibWasm/Printer/Printer.h index 4d1b87322c4..3be6f367824 100644 --- a/Userland/Libraries/LibWasm/Printer/Printer.h +++ b/Userland/Libraries/LibWasm/Printer/Printer.h @@ -50,7 +50,6 @@ struct Printer { void print(Wasm::MemorySection::Memory const&); void print(Wasm::MemoryType const&); void print(Wasm::Module const&); - void print(Wasm::Module::Function const&); void print(Wasm::Reference const&); void print(Wasm::StartSection const&); void print(Wasm::StartSection::StartFunction const&); diff --git a/Userland/Libraries/LibWasm/Types.h b/Userland/Libraries/LibWasm/Types.h index c742bffa0ef..7e8afc45fa5 100644 --- a/Userland/Libraries/LibWasm/Types.h +++ b/Userland/Libraries/LibWasm/Types.h @@ -961,25 +961,6 @@ public: Valid, }; - class Function { - public: - explicit Function(TypeIndex type, Vector local_types, Expression body) - : m_type(type) - , m_local_types(move(local_types)) - , m_body(move(body)) - { - } - - auto& type() const { return m_type; } - auto& locals() const { return m_local_types; } - auto& body() const { return m_body; } - - private: - TypeIndex m_type; - Vector m_local_types; - Expression m_body; - }; - using AnySection = Variant< CustomSection, TypeSection, @@ -1001,14 +982,9 @@ public: explicit Module(Vector sections) : m_sections(move(sections)) { - if (!populate_sections()) { - m_validation_status = ValidationStatus::Invalid; - m_validation_error = "Failed to populate module sections"sv; - } } auto& sections() const { return m_sections; } - auto& functions() const { return m_functions; } auto& type(TypeIndex index) const { FunctionType const* type = nullptr; @@ -1045,11 +1021,9 @@ public: static ParseResult parse(Stream& stream); private: - bool populate_sections(); void set_validation_status(ValidationStatus status) { m_validation_status = status; } Vector m_sections; - Vector m_functions; ValidationStatus m_validation_status { ValidationStatus::Unchecked }; Optional m_validation_error; };