#ifndef WASMTIME_EXN_HH
#define WASMTIME_EXN_HH
#include <wasmtime/conf.h>
#ifdef WASMTIME_FEATURE_GC
#include <vector>
#include <wasmtime/error.hh>
#include <wasmtime/exn.h>
#include <wasmtime/store.hh>
#include <wasmtime/tag.hh>
#include <wasmtime/val.hh>
namespace wasmtime {
class Exn {
struct deleter {
void operator()(wasmtime_exn_t *p) const { wasmtime_exn_delete(p); }
};
std::unique_ptr<wasmtime_exn_t, deleter> ptr;
public:
explicit Exn(wasmtime_exn_t *raw) : ptr(raw) {}
Exn(Exn &&other) = default;
Exn &operator=(Exn &&other) = default;
Exn(const Exn &) = delete;
Exn &operator=(const Exn &) = delete;
~Exn() = default;
static Result<Exn> create(Store::Context cx, const Tag &tag,
const std::vector<Val> &fields) {
wasmtime_exn_t *exn = nullptr;
auto *error = wasmtime_exn_new(
cx.capi(), &tag.capi(),
reinterpret_cast<const wasmtime_val_t *>(fields.data()), fields.size(),
&exn);
if (error != nullptr) {
return Error(error);
}
return Exn(exn);
}
Result<Tag> tag(Store::Context cx) const {
wasmtime_tag_t tag;
auto *error = wasmtime_exn_tag(cx.capi(), ptr.get(), &tag);
if (error != nullptr) {
return Error(error);
}
return Tag(tag);
}
size_t field_count(Store::Context cx) const {
return wasmtime_exn_field_count(cx.capi(), ptr.get());
}
Result<Val> field(Store::Context cx, size_t index) const {
wasmtime_val_t val;
auto *error = wasmtime_exn_field(cx.capi(), ptr.get(), index, &val);
if (error != nullptr) {
return Error(error);
}
return Val(val);
}
wasmtime_exn_t *capi() const { return ptr.get(); }
wasmtime_exn_t *release() { return ptr.release(); }
};
inline Trap Store::Context::throw_exception(Exn exn) {
return Trap(wasmtime_context_set_exception(capi(), exn.release()));
}
inline std::optional<Exn> Store::Context::take_exception() {
wasmtime_exn_t *exn = nullptr;
if (wasmtime_context_take_exception(capi(), &exn)) {
return Exn(exn);
}
return std::nullopt;
}
inline bool Store::Context::has_exception() {
return wasmtime_context_has_exception(capi());
}
}
#endif
#endif