forked from M-Labs/nac3
lyken
cf34002179
Achieved through defining all the needed Exception ID constants at link time. Secondly, since `Exception` is `size_t` dependent, `__nac3_raise()` takes an opaque pointer to `Exception`.
80 lines
2.3 KiB
C++
80 lines
2.3 KiB
C++
#pragma once
|
|
|
|
#include <irrt/cslice.hpp>
|
|
#include <irrt/cstr_util.hpp>
|
|
#include <irrt/int_types.hpp>
|
|
|
|
/**
|
|
* @brief The int type of ARTIQ exception IDs.
|
|
*/
|
|
typedef int32_t ExceptionId;
|
|
|
|
/*
|
|
* Set of exceptions C++ IRRT can use.
|
|
* Must be synchronized with `setup_irrt_exceptions` in `nac3core/src/codegen/irrt/mod.rs`.
|
|
*/
|
|
extern "C"
|
|
{
|
|
ExceptionId EXN_INDEX_ERROR;
|
|
ExceptionId EXN_VALUE_ERROR;
|
|
ExceptionId EXN_ASSERTION_ERROR;
|
|
ExceptionId EXN_TYPE_ERROR;
|
|
}
|
|
|
|
/**
|
|
* @brief Extern function to `__nac3_raise`
|
|
*
|
|
* The parameter `err` could be `Exception<int32_t>` or `Exception<int64_t>`. The caller
|
|
* must make sure to pass `Exception`s with the correct `SizeT` depending on the `size_t` of the runtime.
|
|
*/
|
|
extern "C" void __nac3_raise(void *err);
|
|
|
|
namespace
|
|
{
|
|
/**
|
|
* @brief NAC3's Exception struct
|
|
*/
|
|
template <typename SizeT> struct Exception
|
|
{
|
|
ExceptionId id;
|
|
CSlice<SizeT> filename;
|
|
int32_t line;
|
|
int32_t column;
|
|
CSlice<SizeT> function;
|
|
CSlice<SizeT> msg;
|
|
int64_t params[3];
|
|
};
|
|
|
|
const int64_t NO_PARAM = 0;
|
|
|
|
template <typename SizeT>
|
|
void _raise_exception_helper(ExceptionId id, const char *filename, int32_t line, const char *function, const char *msg,
|
|
int64_t param0, int64_t param1, int64_t param2)
|
|
{
|
|
Exception<SizeT> e = {
|
|
.id = id,
|
|
.filename = {.base = (uint8_t *)filename, .len = (int32_t)cstr::length(filename)},
|
|
.line = line,
|
|
.column = 0,
|
|
.function = {.base = (uint8_t *)function, .len = (int32_t)cstr::length(function)},
|
|
.msg = {.base = (uint8_t *)msg, .len = (int32_t)cstr::length(msg)},
|
|
};
|
|
e.params[0] = param0;
|
|
e.params[1] = param1;
|
|
e.params[2] = param2;
|
|
__nac3_raise((void *)&e);
|
|
__builtin_unreachable();
|
|
}
|
|
|
|
/**
|
|
* @brief Raise an exception with location details (location in the IRRT source files).
|
|
* @param SizeT The runtime `size_t` type.
|
|
* @param id The ID of the exception to raise.
|
|
* @param msg A global constant C-string of the error message.
|
|
*
|
|
* `param0` to `param2` are optional format arguments of `msg`. They should be set to
|
|
* `NO_PARAM` to indicate they are unused.
|
|
*/
|
|
#define raise_exception(SizeT, id, msg, param0, param1, param2) \
|
|
_raise_exception_helper<SizeT>(id, __FILE__, __LINE__, __FUNCTION__, msg, param0, param1, param2)
|
|
} // namespace
|