diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-05-10 15:40:49 +0430 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-05-21 00:15:23 +0100 |
commit | efb106069bb434e96aac3391fd2d81ca68007000 (patch) | |
tree | 5076e43293a5d78343dd2647ca5c0c9efe01ecc0 /Userland/Libraries/LibWasm/AbstractMachine | |
parent | 24b2a6c93a6fcb8d539d80dca23a68f8e44528b8 (diff) | |
download | serenity-efb106069bb434e96aac3391fd2d81ca68007000.zip |
LibWasm: Decouple ModuleInstance from the AbstractMachine
This fixes a FIXME and will allow linking only select modules together,
instead of linking every instantiated module into a big mess of exported
entities :P
Diffstat (limited to 'Userland/Libraries/LibWasm/AbstractMachine')
-rw-r--r-- | Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp | 69 | ||||
-rw-r--r-- | Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h | 8 |
2 files changed, 38 insertions, 39 deletions
diff --git a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp index 2ad7ea7c83..9383927c9a 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp +++ b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp @@ -85,10 +85,11 @@ GlobalInstance* Store::get(GlobalAddress address) InstantiationResult AbstractMachine::instantiate(const Module& module, Vector<ExternValue> externs) { + ModuleInstance main_module_instance; Optional<InstantiationResult> instantiation_result; module.for_each_section_of_type<TypeSection>([&](const TypeSection& section) { - m_module_instance.types() = section.types(); + main_module_instance.types() = section.types(); }); // FIXME: Validate stuff @@ -121,8 +122,8 @@ InstantiationResult AbstractMachine::instantiate(const Module& module, Vector<Ex } }); - if (auto result = allocate_all(module, externs, global_values); result.is_error()) { - return result.error(); + if (auto result = allocate_all(module, main_module_instance, externs, global_values); result.has_value()) { + return result.release_value(); } module.for_each_section_of_type<ElementSection>([&](const ElementSection&) { @@ -136,7 +137,7 @@ InstantiationResult AbstractMachine::instantiate(const Module& module, Vector<Ex segment.value().visit( [&](const DataSection::Data::Active& data) { auto frame = make<Frame>( - m_module_instance, + main_module_instance, Vector<Value> {}, data.offset, 1); @@ -150,11 +151,11 @@ InstantiationResult AbstractMachine::instantiate(const Module& module, Vector<Ex [&](const ExternAddress&) { instantiation_result = InstantiationError { "Data segment offset returned an address" }; }); if (instantiation_result.has_value() && instantiation_result->is_error()) return; - if (m_module_instance.memories().size() <= data.index.value()) { - instantiation_result = InstantiationError { String::formatted("Data segment referenced out-of-bounds memory ({}) of max {} entries", data.index.value(), m_module_instance.memories().size()) }; + if (main_module_instance.memories().size() <= data.index.value()) { + instantiation_result = InstantiationError { String::formatted("Data segment referenced out-of-bounds memory ({}) of max {} entries", data.index.value(), main_module_instance.memories().size()) }; return; } - auto address = m_module_instance.memories()[data.index.value()]; + auto address = main_module_instance.memories()[data.index.value()]; if (auto instance = m_store.get(address)) { if (instance->type().limits().max().value_or(data.init.size() + offset + 1) <= data.init.size() + offset) { instantiation_result = InstantiationError { String::formatted("Data segment attempted to write to out-of-bounds memory ({}) of max {} bytes", data.init.size() + offset, instance->type().limits().max().value()) }; @@ -171,7 +172,7 @@ InstantiationResult AbstractMachine::instantiate(const Module& module, Vector<Ex }); module.for_each_section_of_type<StartSection>([&](const StartSection& section) { - auto& functions = m_module_instance.functions(); + auto& functions = main_module_instance.functions(); auto index = section.function().index(); if (functions.size() <= index.value()) { instantiation_result = InstantiationError { String::formatted("Start section function referenced invalid index {} of max {} entries", index.value(), functions.size()) }; @@ -180,34 +181,34 @@ InstantiationResult AbstractMachine::instantiate(const Module& module, Vector<Ex invoke(functions[index.value()], {}); }); - return instantiation_result.value_or({}); + return instantiation_result.value_or(move(main_module_instance)); } -InstantiationResult AbstractMachine::allocate_all(const Module& module, Vector<ExternValue>& externs, Vector<Value>& global_values) +Optional<InstantiationError> AbstractMachine::allocate_all(const Module& module, ModuleInstance& module_instance, Vector<ExternValue>& externs, Vector<Value>& global_values) { - Optional<InstantiationResult> result; + Optional<InstantiationError> result; for (auto& entry : externs) { entry.visit( - [&](const FunctionAddress& address) { m_module_instance.functions().append(address); }, - [&](const TableAddress& address) { m_module_instance.tables().append(address); }, - [&](const MemoryAddress& address) { m_module_instance.memories().append(address); }, - [&](const GlobalAddress& address) { m_module_instance.globals().append(address); }); + [&](const FunctionAddress& address) { module_instance.functions().append(address); }, + [&](const TableAddress& address) { module_instance.tables().append(address); }, + [&](const MemoryAddress& address) { module_instance.memories().append(address); }, + [&](const GlobalAddress& address) { module_instance.globals().append(address); }); } // FIXME: What if this fails? for (auto& func : module.functions()) { - auto address = m_store.allocate(m_module_instance, func); + auto address = m_store.allocate(module_instance, func); VERIFY(address.has_value()); - m_module_instance.functions().append(*address); + module_instance.functions().append(*address); } module.for_each_section_of_type<TableSection>([&](const TableSection& section) { for (auto& table : section.tables()) { auto table_address = m_store.allocate(table.type()); VERIFY(table_address.has_value()); - m_module_instance.tables().append(*table_address); + module_instance.tables().append(*table_address); } }); @@ -215,7 +216,7 @@ InstantiationResult AbstractMachine::allocate_all(const Module& module, Vector<E for (auto& memory : section.memories()) { auto memory_address = m_store.allocate(memory.type()); VERIFY(memory_address.has_value()); - m_module_instance.memories().append(*memory_address); + module_instance.memories().append(*memory_address); } }); @@ -224,7 +225,7 @@ InstantiationResult AbstractMachine::allocate_all(const Module& module, Vector<E for (auto& entry : section.entries()) { auto address = m_store.allocate(entry.type(), global_values[index]); VERIFY(address.has_value()); - m_module_instance.globals().append(*address); + module_instance.globals().append(*address); index++; } }); @@ -234,28 +235,28 @@ InstantiationResult AbstractMachine::allocate_all(const Module& module, Vector<E Variant<FunctionAddress, TableAddress, MemoryAddress, GlobalAddress, Empty> address { Empty {} }; entry.description().visit( [&](const FunctionIndex& index) { - if (m_module_instance.functions().size() > index.value()) - address = FunctionAddress { m_module_instance.functions()[index.value()] }; + if (module_instance.functions().size() > index.value()) + address = FunctionAddress { module_instance.functions()[index.value()] }; else - dbgln("Failed to export '{}', the exported address ({}) was out of bounds (min: 0, max: {})", entry.name(), index.value(), m_module_instance.functions().size()); + dbgln("Failed to export '{}', the exported address ({}) was out of bounds (min: 0, max: {})", entry.name(), index.value(), module_instance.functions().size()); }, [&](const TableIndex& index) { - if (m_module_instance.tables().size() > index.value()) - address = TableAddress { m_module_instance.tables()[index.value()] }; + if (module_instance.tables().size() > index.value()) + address = TableAddress { module_instance.tables()[index.value()] }; else - dbgln("Failed to export '{}', the exported address ({}) was out of bounds (min: 0, max: {})", entry.name(), index.value(), m_module_instance.tables().size()); + dbgln("Failed to export '{}', the exported address ({}) was out of bounds (min: 0, max: {})", entry.name(), index.value(), module_instance.tables().size()); }, [&](const MemoryIndex& index) { - if (m_module_instance.memories().size() > index.value()) - address = MemoryAddress { m_module_instance.memories()[index.value()] }; + if (module_instance.memories().size() > index.value()) + address = MemoryAddress { module_instance.memories()[index.value()] }; else - dbgln("Failed to export '{}', the exported address ({}) was out of bounds (min: 0, max: {})", entry.name(), index.value(), m_module_instance.memories().size()); + dbgln("Failed to export '{}', the exported address ({}) was out of bounds (min: 0, max: {})", entry.name(), index.value(), module_instance.memories().size()); }, [&](const GlobalIndex& index) { - if (m_module_instance.globals().size() > index.value()) - address = GlobalAddress { m_module_instance.globals()[index.value()] }; + if (module_instance.globals().size() > index.value()) + address = GlobalAddress { module_instance.globals()[index.value()] }; else - dbgln("Failed to export '{}', the exported address ({}) was out of bounds (min: 0, max: {})", entry.name(), index.value(), m_module_instance.globals().size()); + dbgln("Failed to export '{}', the exported address ({}) was out of bounds (min: 0, max: {})", entry.name(), index.value(), module_instance.globals().size()); }); if (address.has<Empty>()) { @@ -263,14 +264,14 @@ InstantiationResult AbstractMachine::allocate_all(const Module& module, Vector<E continue; } - m_module_instance.exports().append(ExportInstance { + module_instance.exports().append(ExportInstance { entry.name(), move(address).downcast<FunctionAddress, TableAddress, MemoryAddress, GlobalAddress>(), }); } }); - return result.value_or({}); + return result; } Result AbstractMachine::invoke(FunctionAddress address, Vector<Value> arguments) diff --git a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h index 94f5e29ce9..1f06b76f79 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h +++ b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h @@ -15,7 +15,6 @@ namespace Wasm { struct InstantiationError { String error { "Unknown error" }; }; -using InstantiationResult = Result<void, InstantiationError>; TYPEDEF_DISTINCT_NUMERIC_GENERAL(u64, true, true, false, false, false, true, FunctionAddress); TYPEDEF_DISTINCT_NUMERIC_GENERAL(u64, true, true, false, false, false, true, ExternAddress); @@ -419,6 +418,8 @@ private: Vector<EntryType> m_data; }; +using InstantiationResult = AK::Result<ModuleInstance, InstantiationError>; + class AbstractMachine { public: explicit AbstractMachine() = default; @@ -427,14 +428,11 @@ public: InstantiationResult instantiate(const Module&, Vector<ExternValue>); Result invoke(FunctionAddress, Vector<Value>); - auto& module_instance() const { return m_module_instance; } - auto& module_instance() { return m_module_instance; } auto& store() const { return m_store; } auto& store() { return m_store; } private: - InstantiationResult allocate_all(const Module&, Vector<ExternValue>&, Vector<Value>& global_values); - ModuleInstance m_module_instance; + Optional<InstantiationError> allocate_all(const Module&, ModuleInstance&, Vector<ExternValue>&, Vector<Value>& global_values); Store m_store; }; |