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.
This commit is contained in:
Ali Mohammad Pur 2021-05-24 01:28:02 +04:30 committed by Ali Mohammad Pur
parent b2bd5132c4
commit f91fa79fc5
Notes: sideshowbarker 2024-07-18 17:19:48 +09:00
3 changed files with 40 additions and 5 deletions

View file

@ -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();
}

View file

@ -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();

View file

@ -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;