Make m_throw a classic "cold" function rather than a static inline function.
Since the function shall be rarely called, there is no point in inlining/duplicating it in several units.
This commit is contained in:
1 parent
7279011f0a
commit
5158059ec4
1 file changed
+51
-51
@@ -266,11 +266,6 @@ typedef intptr_t m_try_jmp_buf[5];
|
|||||||
#define M_CATCH_B(name, error_code) \
|
#define M_CATCH_B(name, error_code) \
|
||||||
else if (m_catch( M_C(m_try_buf_, name), (error_code), &name))
|
else if (m_catch( M_C(m_try_buf_, name), (error_code), &name))
|
||||||
|
|
||||||
// Macro to add once in one source file to define theses global:
|
|
||||||
#define M_TRY_DEF_ONCE_B() \
|
|
||||||
M_THREAD_ATTR struct m_try_s *m_global_error_list; \
|
|
||||||
M_THREAD_ATTR struct m_exception_s m_global_exception;
|
|
||||||
|
|
||||||
// Define the operator to define nested functions (GCC) or blocks (CLANG)
|
// Define the operator to define nested functions (GCC) or blocks (CLANG)
|
||||||
#if M_USE_TRY_MECHANISM == 2
|
#if M_USE_TRY_MECHANISM == 2
|
||||||
# define M_TRY_FUNC_OPERATOR ^
|
# define M_TRY_FUNC_OPERATOR ^
|
||||||
@@ -309,10 +304,6 @@ typedef struct m_try_s {
|
|||||||
m_throw( &(const struct m_exception_s) { error_code, __LINE__, M_NARGS(__VA_ARGS__), __FILE__, \
|
m_throw( &(const struct m_exception_s) { error_code, __LINE__, M_NARGS(__VA_ARGS__), __FILE__, \
|
||||||
{ __VA_ARGS__ } } )
|
{ __VA_ARGS__ } } )
|
||||||
|
|
||||||
// The global thread attribute variables.
|
|
||||||
extern M_THREAD_ATTR struct m_try_s *m_global_error_list;
|
|
||||||
extern M_THREAD_ATTR struct m_exception_s m_global_exception;
|
|
||||||
|
|
||||||
// Copy an exception to another.
|
// Copy an exception to another.
|
||||||
static inline void
|
static inline void
|
||||||
m_exception_set(struct m_exception_s *out, const struct m_exception_s *in)
|
m_exception_set(struct m_exception_s *out, const struct m_exception_s *in)
|
||||||
@@ -322,50 +313,47 @@ m_exception_set(struct m_exception_s *out, const struct m_exception_s *in)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the state to a TRY state.
|
// The global thread attribute variables and functions.
|
||||||
static inline void
|
extern M_THREAD_ATTR struct m_try_s *m_global_error_list;
|
||||||
m_try_init(m_try_t state)
|
extern M_THREAD_ATTR struct m_exception_s m_global_exception;
|
||||||
{
|
extern M_ATTR_NO_RETURN M_ATTR_COLD_FUNCTION void m_throw(const struct m_exception_s *exception);
|
||||||
state->kind = M_STATE_TRY;
|
|
||||||
state->next = m_global_error_list;
|
|
||||||
m_global_error_list = state;
|
|
||||||
// setjmp needs to be done in the MACRO.
|
|
||||||
}
|
|
||||||
#define m_try_init(s) \
|
|
||||||
M_LIKELY ((m_try_init(s), m_try_setjmp(((s)->data.buf)) != 1))
|
|
||||||
|
|
||||||
// Throw the given exception
|
// Macro to add once in one source file to define theses global:
|
||||||
// This function should be rarely called.
|
#define M_TRY_DEF_ONCE_B() \
|
||||||
static inline M_ATTR_NO_RETURN M_ATTR_COLD_FUNCTION void
|
M_THREAD_ATTR struct m_try_s *m_global_error_list; \
|
||||||
m_throw(const struct m_exception_s *exception)
|
M_THREAD_ATTR struct m_exception_s m_global_exception; \
|
||||||
{
|
\
|
||||||
// Analyze the error list to see what has been registered
|
/* Throw the given exception \
|
||||||
struct m_try_s *e = m_global_error_list;
|
This function should be rarely called. */ \
|
||||||
while (e != NULL) {
|
M_ATTR_NO_RETURN M_ATTR_COLD_FUNCTION void \
|
||||||
// A CLEAR operator has been registered
|
m_throw(const struct m_exception_s *exception) \
|
||||||
// Call it
|
{ \
|
||||||
if (e->kind == M_STATE_CLEAR_CB) {
|
/* Analyze the error list to see what has been registered */ \
|
||||||
e->data.clear.func(e->data.clear.data);
|
struct m_try_s *e = m_global_error_list; \
|
||||||
}
|
while (e != NULL) { \
|
||||||
else {
|
/* A CLEAR operator has been registered: call it */ \
|
||||||
// A JUMP command has been registered.
|
if (e->kind == M_STATE_CLEAR_CB) { \
|
||||||
// Either due to the M_TRY block
|
e->data.clear.func(e->data.clear.data); \
|
||||||
// or because of the jump to the CLEAR operator of the object to clear.
|
} \
|
||||||
M_ASSERT(e->kind == M_STATE_TRY || e->kind == M_STATE_CLEAR_JMPBUF);
|
else { \
|
||||||
// If the exception is already m_global_exception, it won't be copied
|
/* A JUMP command has been registered. \
|
||||||
m_exception_set(&m_global_exception, exception);
|
* Either due to the M_TRY block or \
|
||||||
e->kind = M_STATE_EXCEPTION_IN_PROGRESS;
|
* because of the jump to the CLEAR operator of the object to clear. */ \
|
||||||
m_global_error_list = e;
|
M_ASSERT(e->kind == M_STATE_TRY || e->kind == M_STATE_CLEAR_JMPBUF); \
|
||||||
m_try_longjmp(e->data.buf, 1);
|
/* If the exception is already m_global_exception, it won't be copied */ \
|
||||||
}
|
m_exception_set(&m_global_exception, exception); \
|
||||||
// Next stack frame
|
e->kind = M_STATE_EXCEPTION_IN_PROGRESS; \
|
||||||
e = e->next;
|
m_global_error_list = e; \
|
||||||
|
m_try_longjmp(e->data.buf, 1); \
|
||||||
|
} \
|
||||||
|
/* Next stack frame */ \
|
||||||
|
e = e->next; \
|
||||||
|
} \
|
||||||
|
/* No exception found. \
|
||||||
|
Display the information and halt program . */ \
|
||||||
|
M_RAISE_FATAL("Exception '%u' raised by (%s:%d) is not catched. Program aborted.\n", \
|
||||||
|
exception->error_code, exception->filename, exception->line); \
|
||||||
}
|
}
|
||||||
// No exception found.
|
|
||||||
// Display the information.
|
|
||||||
M_RAISE_FATAL("Exception '%u' raised by (%s:%d) is not catched. Program aborted.\n",
|
|
||||||
exception->error_code, exception->filename, exception->line);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rethrow the error
|
// Rethrow the error
|
||||||
static inline void
|
static inline void
|
||||||
@@ -393,6 +381,18 @@ m_catch(m_try_t state, unsigned error_code, const struct m_exception_s **excepti
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize the state to a TRY state.
|
||||||
|
static inline void
|
||||||
|
m_try_init(m_try_t state)
|
||||||
|
{
|
||||||
|
state->kind = M_STATE_TRY;
|
||||||
|
state->next = m_global_error_list;
|
||||||
|
m_global_error_list = state;
|
||||||
|
// setjmp needs to be done in the MACRO.
|
||||||
|
}
|
||||||
|
#define m_try_init(s) \
|
||||||
|
M_LIKELY ((m_try_init(s), m_try_setjmp(((s)->data.buf)) != 1))
|
||||||
|
|
||||||
// Disable the current TRY block.
|
// Disable the current TRY block.
|
||||||
static inline void
|
static inline void
|
||||||
m_try_clear(m_try_t state)
|
m_try_clear(m_try_t state)
|
||||||
|
|||||||
Reference in new issue
Block a user