mirror of
https://github.com/RGBCube/serenity
synced 2025-07-17 07:27:35 +00:00
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:
parent
b2bd5132c4
commit
f91fa79fc5
3 changed files with 40 additions and 5 deletions
|
@ -22,6 +22,16 @@ Optional<Label> Configuration::nth_label(size_t i)
|
||||||
return {};
|
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)
|
Result Configuration::call(FunctionAddress address, Vector<Value> arguments)
|
||||||
{
|
{
|
||||||
auto* function = m_store.get(address);
|
auto* function = m_store.get(address);
|
||||||
|
@ -41,6 +51,7 @@ Result Configuration::call(FunctionAddress address, Vector<Value> arguments)
|
||||||
wasm_function->code().body(),
|
wasm_function->code().body(),
|
||||||
wasm_function->type().results().size(),
|
wasm_function->type().results().size(),
|
||||||
});
|
});
|
||||||
|
m_ip = 0;
|
||||||
return execute();
|
return execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,28 @@ public:
|
||||||
auto& store() const { return m_store; }
|
auto& store() const { return m_store; }
|
||||||
auto& store() { 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 call(FunctionAddress, Vector<Value> arguments);
|
||||||
Result execute();
|
Result execute();
|
||||||
|
|
||||||
|
|
|
@ -125,11 +125,13 @@ void Interpreter::call_address(Configuration& configuration, FunctionAddress add
|
||||||
for (size_t i = 0; i < type->parameters().size(); ++i) {
|
for (size_t i = 0; i < type->parameters().size(); ++i) {
|
||||||
args.prepend(move(configuration.stack().pop().get<Value>()));
|
args.prepend(move(configuration.stack().pop().get<Value>()));
|
||||||
}
|
}
|
||||||
Configuration function_configuration { configuration.store() };
|
|
||||||
function_configuration.pre_interpret_hook = pre_interpret_hook;
|
Result result { Trap {} };
|
||||||
function_configuration.post_interpret_hook = post_interpret_hook;
|
{
|
||||||
function_configuration.depth() = configuration.depth() + 1;
|
Configuration::CallFrameHandle handle { configuration };
|
||||||
auto result = function_configuration.call(address, move(args));
|
result = configuration.call(address, move(args));
|
||||||
|
}
|
||||||
|
|
||||||
if (result.is_trap()) {
|
if (result.is_trap()) {
|
||||||
m_do_trap = true;
|
m_do_trap = true;
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue