forked from M-Labs/nac3
92 lines
2.6 KiB
C++
92 lines
2.6 KiB
C++
#pragma once
|
|
|
|
#include <irrt/artiq_defs.hpp>
|
|
#include <irrt/int_defs.hpp>
|
|
#include <irrt/utils.hpp>
|
|
|
|
namespace {
|
|
/**
|
|
* @brief A (limited) set of known Exception IDs usable in IRRT
|
|
*/
|
|
struct ErrorContextExceptions {
|
|
ExceptionId index_error;
|
|
ExceptionId value_error;
|
|
ExceptionId assertion_error;
|
|
ExceptionId runtime_error;
|
|
ExceptionId type_error;
|
|
};
|
|
|
|
/**
|
|
* @brief The IRRT error context object
|
|
*
|
|
* This object contains all the details needed to propagate Python-like Exceptions in
|
|
* IRRT - within IRRT itself or propagate out of extern calls from nac3core.
|
|
*/
|
|
struct ErrorContext {
|
|
const ErrorContextExceptions *exceptions;
|
|
|
|
// Exception thrown by IRRT
|
|
ExceptionId exception_id;
|
|
// Points to empty c-string if there is no thrown Exception
|
|
const char *msg;
|
|
uint64_t param1;
|
|
uint64_t param2;
|
|
uint64_t param3;
|
|
|
|
void initialize(const ErrorContextExceptions *exceptions) {
|
|
this->exceptions = exceptions;
|
|
clear_error();
|
|
}
|
|
|
|
void clear_error() {
|
|
// NOTE: Point the msg to an empty str.
|
|
// Don't set it to nullptr - to implement `has_exception`
|
|
this->msg = "";
|
|
}
|
|
|
|
void set_exception(ExceptionId exception_id, const char *msg,
|
|
uint64_t param1 = 0, uint64_t param2 = 0,
|
|
uint64_t param3 = 0) {
|
|
this->exception_id = exception_id;
|
|
this->msg = msg;
|
|
this->param1 = param1;
|
|
this->param2 = param2;
|
|
this->param3 = param3;
|
|
}
|
|
|
|
bool has_exception() { return !cstr_utils::is_empty(msg); }
|
|
|
|
template <typename SizeT>
|
|
void get_exception_str(CSlice<SizeT> *dst_str) {
|
|
dst_str->base = msg;
|
|
dst_str->len = (SizeT)cstr_utils::length(msg);
|
|
}
|
|
};
|
|
} // namespace
|
|
|
|
extern "C" {
|
|
void __nac3_error_context_initialize(ErrorContext *errctx,
|
|
ErrorContextExceptions *exceptions) {
|
|
errctx->initialize(exceptions);
|
|
}
|
|
|
|
bool __nac3_error_context_has_exception(ErrorContext *errctx) {
|
|
return errctx->has_exception();
|
|
}
|
|
|
|
void __nac3_error_context_get_exception_str(ErrorContext *errctx,
|
|
CSlice<int32_t> *dst_str) {
|
|
errctx->get_exception_str<int32_t>(dst_str);
|
|
}
|
|
|
|
void __nac3_error_context_get_exception_str64(ErrorContext *errctx,
|
|
CSlice<int64_t> *dst_str) {
|
|
errctx->get_exception_str<int64_t>(dst_str);
|
|
}
|
|
|
|
// Used for testing
|
|
void __nac3_error_dummy_raise(ErrorContext *errctx) {
|
|
errctx->set_exception(errctx->exceptions->runtime_error,
|
|
"Error thrown from __nac3_error_dummy_raise");
|
|
}
|
|
} |