ソースを参照

LibWasm: Use the current configuration to run call ops

This should make it easier to implement multiple types of interpreters
on top of a configuration, and also give a small speed boost in not
initialising as many Stack objects.
Ali Mohammad Pur 4 年 前
コミット
f91fa79fc5

+ 11 - 0
Userland/Libraries/LibWasm/AbstractMachine/Configuration.cpp

@@ -22,6 +22,16 @@ Optional<Label> Configuration::nth_label(size_t i)
     return {};
 }
 
+void Configuration::unwind(Badge<CallFrameHandle>, const CallFrameHandle& frame_handle)
+{
+    VERIFY(m_stack.size() > frame_handle.stack_size);
+    m_stack.entries().remove(frame_handle.stack_size, m_stack.size() - frame_handle.stack_size);
+    m_current_frame_index = frame_handle.frame_index;
+    m_depth--;
+    m_ip = frame_handle.ip;
+    VERIFY(m_stack.size() == frame_handle.stack_size);
+}
+
 Result Configuration::call(FunctionAddress address, Vector<Value> arguments)
 {
     auto* function = m_store.get(address);
@@ -41,6 +51,7 @@ Result Configuration::call(FunctionAddress address, Vector<Value> arguments)
             wasm_function->code().body(),
             wasm_function->type().results().size(),
         });
+        m_ip = 0;
         return execute();
     }
 

+ 22 - 0
Userland/Libraries/LibWasm/AbstractMachine/Configuration.h

@@ -36,6 +36,28 @@ public:
     auto& store() const { return m_store; }
     auto& store() { return m_store; }
 
+    struct CallFrameHandle {
+        explicit CallFrameHandle(Configuration& configuration)
+            : frame_index(configuration.m_current_frame_index)
+            , stack_size(configuration.m_stack.size())
+            , ip(configuration.ip())
+            , configuration(configuration)
+        {
+            configuration.depth()++;
+        }
+
+        ~CallFrameHandle()
+        {
+            configuration.unwind({}, *this);
+        }
+
+        size_t frame_index { 0 };
+        size_t stack_size { 0 };
+        InstructionPointer ip { 0 };
+        Configuration& configuration;
+    };
+
+    void unwind(Badge<CallFrameHandle>, const CallFrameHandle&);
     Result call(FunctionAddress, Vector<Value> arguments);
     Result execute();
 

+ 7 - 5
Userland/Libraries/LibWasm/AbstractMachine/Interpreter.cpp

@@ -125,11 +125,13 @@ void Interpreter::call_address(Configuration& configuration, FunctionAddress add
     for (size_t i = 0; i < type->parameters().size(); ++i) {
         args.prepend(move(configuration.stack().pop().get<Value>()));
     }
-    Configuration function_configuration { configuration.store() };
-    function_configuration.pre_interpret_hook = pre_interpret_hook;
-    function_configuration.post_interpret_hook = post_interpret_hook;
-    function_configuration.depth() = configuration.depth() + 1;
-    auto result = function_configuration.call(address, move(args));
+
+    Result result { Trap {} };
+    {
+        Configuration::CallFrameHandle handle { configuration };
+        result = configuration.call(address, move(args));
+    }
+
     if (result.is_trap()) {
         m_do_trap = true;
         return;