mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:07:47 +00:00
LibWasm+LibWeb: Sneak a JS::Completion into Wasm::Result
Imported functions in Wasm may throw JS exceptions, and we need to preserve these exceptions so we can pass them to the calling JS code. This also adds a `assert_wasm_result()` API to Result for cases where only Wasm traps or values are expected (e.g. internal uses) to avoid making LibWasm (pointlessly) handle JS exceptions that will never show up in reality.
This commit is contained in:
parent
1c3050245e
commit
6b50f23242
11 changed files with 95 additions and 35 deletions
|
@ -13,6 +13,9 @@
|
|||
#include <AK/Result.h>
|
||||
#include <LibWasm/Types.h>
|
||||
|
||||
// NOTE: Special case for Wasm::Result.
|
||||
#include <LibJS/Runtime/Completion.h>
|
||||
|
||||
namespace Wasm {
|
||||
|
||||
class Configuration;
|
||||
|
@ -171,6 +174,35 @@ struct Trap {
|
|||
DeprecatedString reason;
|
||||
};
|
||||
|
||||
// A variant of Result that does not include external reasons for error (JS::Completion, for now).
|
||||
class PureResult {
|
||||
public:
|
||||
explicit PureResult(Vector<Value> values)
|
||||
: m_result(move(values))
|
||||
{
|
||||
}
|
||||
|
||||
PureResult(Trap trap)
|
||||
: m_result(move(trap))
|
||||
{
|
||||
}
|
||||
|
||||
auto is_trap() const { return m_result.has<Trap>(); }
|
||||
auto& values() const { return m_result.get<Vector<Value>>(); }
|
||||
auto& values() { return m_result.get<Vector<Value>>(); }
|
||||
auto& trap() const { return m_result.get<Trap>(); }
|
||||
auto& trap() { return m_result.get<Trap>(); }
|
||||
|
||||
private:
|
||||
friend class Result;
|
||||
explicit PureResult(Variant<Vector<Value>, Trap>&& result)
|
||||
: m_result(move(result))
|
||||
{
|
||||
}
|
||||
|
||||
Variant<Vector<Value>, Trap> m_result;
|
||||
};
|
||||
|
||||
class Result {
|
||||
public:
|
||||
explicit Result(Vector<Value> values)
|
||||
|
@ -183,14 +215,34 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
Result(JS::Completion completion)
|
||||
: m_result(move(completion))
|
||||
{
|
||||
VERIFY(m_result.get<JS::Completion>().is_abrupt());
|
||||
}
|
||||
|
||||
Result(PureResult&& result)
|
||||
: m_result(result.m_result.downcast<decltype(m_result)>())
|
||||
{
|
||||
}
|
||||
|
||||
auto is_trap() const { return m_result.has<Trap>(); }
|
||||
auto is_completion() const { return m_result.has<JS::Completion>(); }
|
||||
auto& values() const { return m_result.get<Vector<Value>>(); }
|
||||
auto& values() { return m_result.get<Vector<Value>>(); }
|
||||
auto& trap() const { return m_result.get<Trap>(); }
|
||||
auto& trap() { return m_result.get<Trap>(); }
|
||||
auto& completion() { return m_result.get<JS::Completion>(); }
|
||||
auto& completion() const { return m_result.get<JS::Completion>(); }
|
||||
|
||||
PureResult assert_wasm_result() &&
|
||||
{
|
||||
VERIFY(!is_completion());
|
||||
return PureResult(move(m_result).downcast<Vector<Value>, Trap>());
|
||||
}
|
||||
|
||||
private:
|
||||
Variant<Vector<Value>, Trap> m_result;
|
||||
Variant<Vector<Value>, Trap, JS::Completion> m_result;
|
||||
};
|
||||
|
||||
using ExternValue = Variant<FunctionAddress, TableAddress, MemoryAddress, GlobalAddress>;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue