diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-05-23 21:42:19 +0430 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2021-05-27 17:28:41 +0430 |
commit | bc936a5fac14165a1d75ccd16ecae22dfd25582d (patch) | |
tree | 3a86f00cc3462321d9b2bf729a2afe3b45d4bae6 /Userland/Libraries/LibWasm/AbstractMachine | |
parent | 73eb0785e0f791d535c803907f347ecb81f929b5 (diff) | |
download | serenity-bc936a5fac14165a1d75ccd16ecae22dfd25582d.zip |
LibWasm: Make Frame a value type as well
This means stack operations will no longer do extra allocations.
Diffstat (limited to 'Userland/Libraries/LibWasm/AbstractMachine')
5 files changed, 48 insertions, 49 deletions
diff --git a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp index 49704fddd4..210d73e487 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp +++ b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp @@ -107,15 +107,15 @@ InstantiationResult AbstractMachine::instantiate(const Module& module, Vector<Ex module.for_each_section_of_type<GlobalSection>([&](auto& global_section) { for (auto& entry : global_section.entries()) { - auto frame = make<Frame>( - auxiliary_instance, - Vector<Value> {}, - entry.expression(), - 1); Configuration config { m_store }; config.pre_interpret_hook = &pre_interpret_hook; config.post_interpret_hook = &post_interpret_hook; - config.set_frame(move(frame)); + config.set_frame(Frame { + auxiliary_instance, + Vector<Value> {}, + entry.expression(), + 1, + }); auto result = config.execute(); // What if this traps? if (result.is_trap()) @@ -139,15 +139,15 @@ InstantiationResult AbstractMachine::instantiate(const Module& module, Vector<Ex for (auto& segment : data_section.data()) { segment.value().visit( [&](const DataSection::Data::Active& data) { - auto frame = make<Frame>( - main_module_instance, - Vector<Value> {}, - data.offset, - 1); Configuration config { m_store }; config.pre_interpret_hook = &pre_interpret_hook; config.post_interpret_hook = &post_interpret_hook; - config.set_frame(move(frame)); + config.set_frame(Frame { + main_module_instance, + Vector<Value> {}, + data.offset, + 1, + }); auto result = config.execute(); size_t offset = 0; result.values().first().value().visit( diff --git a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h index 346f93dee9..0b786c457c 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h +++ b/Userland/Libraries/LibWasm/AbstractMachine/AbstractMachine.h @@ -392,8 +392,6 @@ private: }; class Frame { - AK_MAKE_NONCOPYABLE(Frame); - public: explicit Frame(const ModuleInstance& module, Vector<Value> locals, const Expression& expression, size_t arity) : m_module(module) @@ -418,7 +416,7 @@ private: class Stack { public: - using EntryType = Variant<Value, Label, NonnullOwnPtr<Frame>>; + using EntryType = Variant<Value, Label, Frame>; Stack() = default; [[nodiscard]] bool is_empty() const { return m_data.is_empty(); } @@ -428,9 +426,10 @@ public: auto size() const { return m_data.size(); } auto& entries() const { return m_data; } + auto& entries() { return m_data; } private: - Vector<EntryType> m_data; + Vector<EntryType, 64> m_data; }; using InstantiationResult = AK::Result<NonnullOwnPtr<ModuleInstance>, InstantiationError>; diff --git a/Userland/Libraries/LibWasm/AbstractMachine/Configuration.cpp b/Userland/Libraries/LibWasm/AbstractMachine/Configuration.cpp index 5bc8628008..b73f25261e 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/Configuration.cpp +++ b/Userland/Libraries/LibWasm/AbstractMachine/Configuration.cpp @@ -35,13 +35,12 @@ Result Configuration::call(FunctionAddress address, Vector<Value> arguments) for (auto& type : wasm_function->code().locals()) locals.empend(type, 0ull); - auto frame = make<Frame>( + set_frame(Frame { wasm_function->module(), move(locals), wasm_function->code().body(), - wasm_function->type().results().size()); - - set_frame(move(frame)); + wasm_function->type().results().size(), + }); return execute(); } @@ -61,8 +60,8 @@ Result Configuration::execute() return Trap {}; Vector<Value> results; - results.ensure_capacity(m_current_frame->arity()); - for (size_t i = 0; i < m_current_frame->arity(); ++i) + results.ensure_capacity(frame().arity()); + for (size_t i = 0; i < frame().arity(); ++i) results.append(move(stack().pop().get<Value>())); auto label = stack().pop(); // ASSERT: label == current frame @@ -83,9 +82,9 @@ void Configuration::dump_stack() dbgln(" *{}", v.value()); }); }, - [](const NonnullOwnPtr<Frame>& f) { - dbgln(" frame({})", f->arity()); - for (auto& local : f->locals()) { + [](const Frame& f) { + dbgln(" frame({})", f.arity()); + for (auto& local : f.locals()) { local.value().visit([]<typename T>(const T& v) { if constexpr (IsIntegral<T> || IsFloatingPoint<T>) dbgln(" {}", v); diff --git a/Userland/Libraries/LibWasm/AbstractMachine/Configuration.h b/Userland/Libraries/LibWasm/AbstractMachine/Configuration.h index 8b792c1535..70658c447b 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/Configuration.h +++ b/Userland/Libraries/LibWasm/AbstractMachine/Configuration.h @@ -18,14 +18,15 @@ public: } Optional<Label> nth_label(size_t); - void set_frame(NonnullOwnPtr<Frame> frame) + void set_frame(Frame&& frame) { - m_current_frame = frame.ptr(); + m_current_frame_index = m_stack.size(); + Label label(frame.arity(), frame.expression().instructions().size()); m_stack.push(move(frame)); - m_stack.push(Label(m_current_frame->arity(), m_current_frame->expression().instructions().size())); + m_stack.push(label); } - auto& frame() const { return m_current_frame; } - auto& frame() { return m_current_frame; } + auto& frame() const { return m_stack.entries()[m_current_frame_index].get<Frame>(); } + auto& frame() { return m_stack.entries()[m_current_frame_index].get<Frame>(); } auto& ip() const { return m_ip; } auto& ip() { return m_ip; } auto& depth() const { return m_depth; } @@ -45,7 +46,7 @@ public: private: Store& m_store; - Frame* m_current_frame { nullptr }; + size_t m_current_frame_index { 0 }; Stack m_stack; size_t m_depth { 0 }; InstructionPointer m_ip; diff --git a/Userland/Libraries/LibWasm/AbstractMachine/Interpreter.cpp b/Userland/Libraries/LibWasm/AbstractMachine/Interpreter.cpp index c557610054..5d5eb1a0be 100644 --- a/Userland/Libraries/LibWasm/AbstractMachine/Interpreter.cpp +++ b/Userland/Libraries/LibWasm/AbstractMachine/Interpreter.cpp @@ -31,7 +31,7 @@ namespace Wasm { void Interpreter::interpret(Configuration& configuration) { - auto& instructions = configuration.frame()->expression().instructions(); + auto& instructions = configuration.frame().expression().instructions(); auto max_ip_value = InstructionPointer { instructions.size() }; auto& current_ip_value = configuration.ip(); @@ -73,7 +73,7 @@ void Interpreter::branch_to_label(Configuration& configuration, LabelIndex index ReadonlyBytes Interpreter::load_from_memory(Configuration& configuration, const Instruction& instruction, size_t size) { - auto& address = configuration.frame()->module().memories().first(); + auto& address = configuration.frame().module().memories().first(); auto memory = configuration.store().get(address); if (!memory) { m_do_trap = true; @@ -97,7 +97,7 @@ ReadonlyBytes Interpreter::load_from_memory(Configuration& configuration, const void Interpreter::store_to_memory(Configuration& configuration, const Instruction& instruction, ReadonlyBytes data) { - auto& address = configuration.frame()->module().memories().first(); + auto& address = configuration.frame().module().memories().first(); auto memory = configuration.store().get(address); TRAP_IF_NOT(memory); auto& arg = instruction.arguments().get<Instruction::MemoryArgument>(); @@ -366,11 +366,11 @@ void Interpreter::interpret(Configuration& configuration, InstructionPointer& ip case Instructions::nop.value(): return; case Instructions::local_get.value(): - configuration.stack().push(Value(configuration.frame()->locals()[instruction.arguments().get<LocalIndex>().value()])); + configuration.stack().push(Value(configuration.frame().locals()[instruction.arguments().get<LocalIndex>().value()])); return; case Instructions::local_set.value(): { auto entry = configuration.stack().pop(); - configuration.frame()->locals()[instruction.arguments().get<LocalIndex>().value()] = move(entry.get<Value>()); + configuration.frame().locals()[instruction.arguments().get<LocalIndex>().value()] = move(entry.get<Value>()); return; } case Instructions::i32_const.value(): @@ -448,7 +448,7 @@ void Interpreter::interpret(Configuration& configuration, InstructionPointer& ip } case Instructions::return_.value(): { Vector<Stack::EntryType> results; - auto& frame = *configuration.frame(); + auto& frame = configuration.frame(); results.ensure_capacity(frame.arity()); for (size_t i = 0; i < frame.arity(); ++i) results.prepend(configuration.stack().pop()); @@ -460,7 +460,7 @@ void Interpreter::interpret(Configuration& configuration, InstructionPointer& ip last_label = entry.get<Label>(); continue; } - if (entry.has<NonnullOwnPtr<Frame>>()) { + if (entry.has<Frame>()) { // Push the frame back configuration.stack().push(move(entry)); // Push its label back (if there is one) @@ -475,7 +475,7 @@ void Interpreter::interpret(Configuration& configuration, InstructionPointer& ip configuration.stack().push(move(result)); // Jump past the call/indirect instruction - configuration.ip() = configuration.frame()->expression().instructions().size() - 1; + configuration.ip() = configuration.frame().expression().instructions().size() - 1; return; } case Instructions::br.value(): @@ -489,14 +489,14 @@ void Interpreter::interpret(Configuration& configuration, InstructionPointer& ip goto unimplemented; case Instructions::call.value(): { auto index = instruction.arguments().get<FunctionIndex>(); - auto address = configuration.frame()->module().functions()[index.value()]; + auto address = configuration.frame().module().functions()[index.value()]; dbgln_if(WASM_TRACE_DEBUG, "call({})", address.value()); call_address(configuration, address); return; } case Instructions::call_indirect.value(): { auto& args = instruction.arguments().get<Instruction::IndirectCallArgs>(); - auto table_address = configuration.frame()->module().tables()[args.table.value()]; + auto table_address = configuration.frame().module().tables()[args.table.value()]; auto table_instance = configuration.store().get(table_address); auto index = configuration.stack().pop().get<Value>().to<i32>(); TRAP_IF_NOT(index.has_value()); @@ -565,15 +565,15 @@ void Interpreter::interpret(Configuration& configuration, InstructionPointer& ip case Instructions::local_tee.value(): { auto value = configuration.stack().peek().get<Value>(); auto local_index = instruction.arguments().get<LocalIndex>(); - TRAP_IF_NOT(configuration.frame()->locals().size() > local_index.value()); + TRAP_IF_NOT(configuration.frame().locals().size() > local_index.value()); dbgln_if(WASM_TRACE_DEBUG, "stack:peek -> locals({})", local_index.value()); - configuration.frame()->locals()[local_index.value()] = move(value); + configuration.frame().locals()[local_index.value()] = move(value); return; } case Instructions::global_get.value(): { auto global_index = instruction.arguments().get<GlobalIndex>(); - TRAP_IF_NOT(configuration.frame()->module().globals().size() > global_index.value()); - auto address = configuration.frame()->module().globals()[global_index.value()]; + TRAP_IF_NOT(configuration.frame().module().globals().size() > global_index.value()); + auto address = configuration.frame().module().globals()[global_index.value()]; dbgln_if(WASM_TRACE_DEBUG, "global({}) -> stack", address.value()); auto global = configuration.store().get(address); configuration.stack().push(Value(global->value())); @@ -581,8 +581,8 @@ void Interpreter::interpret(Configuration& configuration, InstructionPointer& ip } case Instructions::global_set.value(): { auto global_index = instruction.arguments().get<GlobalIndex>(); - TRAP_IF_NOT(configuration.frame()->module().globals().size() > global_index.value()); - auto address = configuration.frame()->module().globals()[global_index.value()]; + TRAP_IF_NOT(configuration.frame().module().globals().size() > global_index.value()); + auto address = configuration.frame().module().globals()[global_index.value()]; auto value = configuration.stack().pop().get<Value>(); dbgln_if(WASM_TRACE_DEBUG, "stack -> global({})", address.value()); auto global = configuration.store().get(address); @@ -590,7 +590,7 @@ void Interpreter::interpret(Configuration& configuration, InstructionPointer& ip return; } case Instructions::memory_size.value(): { - auto address = configuration.frame()->module().memories()[0]; + auto address = configuration.frame().module().memories()[0]; auto instance = configuration.store().get(address); auto pages = instance->size() / Constants::page_size; dbgln_if(WASM_TRACE_DEBUG, "memory.size -> stack({})", pages); @@ -598,7 +598,7 @@ void Interpreter::interpret(Configuration& configuration, InstructionPointer& ip return; } case Instructions::memory_grow.value(): { - auto address = configuration.frame()->module().memories()[0]; + auto address = configuration.frame().module().memories()[0]; auto instance = configuration.store().get(address); i32 old_pages = instance->size() / Constants::page_size; auto new_pages = configuration.stack().pop().get<Value>().to<i32>(); |