libGimbal 0.0.0 (PRERELEASE)
Ultimate C17/C++20 Core Utility Library and Cross-Language Runtime Framework
gimbal_call_stack.h
Go to the documentation of this file.
1
6#ifndef GIMBAL_CALL_STACK_H
7#define GIMBAL_CALL_STACK_H
8
9#include "../core/gimbal_typedefs.h"
10//#include "gimbal_thread.h"
11
12#ifdef __cplusplus
13extern "C" {
14#endif
15
16typedef struct GblSourceLocation {
17 const char* pFile;
18 const char* pFunc;
19 GblSize line;
20 GblSize column;
22
23typedef struct GblCallRecord {
24 GBL_ALIGNAS(64)
25 char message[GBL_CTX_RESULT_MSG_BUFFER_SIZE];
26 GblSourceLocation srcLocation;
27 GBL_RESULT result;
29
30GBL_FORWARD_DECLARE_STRUCT(GblThread);
31
32GBL_INLINE GblThread* GblThread_current (void) GBL_NOEXCEPT;
33
34GBL_EXPORT GblContext* GblThread_context (const GblThread* pSelf) GBL_NOEXCEPT;
35GBL_INLINE GblStackFrame*
36 GblThread_stackFrameTop (const GblThread* pSelf) GBL_NOEXCEPT;
37
38GBL_INLINE void GBL_CALL_RECORD_CONSTRUCT(GblCallRecord* pRecord, struct GblObject* pObject, GBL_RESULT resultCode, GblSourceLocation source, const char* pFmt, ...) GBL_NOEXCEPT {
39 va_list varArgs;
40 va_start(varArgs, pFmt);
41 pRecord->result = GBL_RESULT_UNKNOWN;
42 pRecord->message[0] = '\0';
43 pRecord->srcLocation.pFile = pRecord->srcLocation.pFunc = GBL_NULL;
44 if(pFmt) GBL_UNLIKELY vsnprintf(pRecord->message, sizeof(pRecord->message), pFmt, varArgs);
45 va_end(varArgs);
46 pRecord->srcLocation = source;
47 pRecord->result = resultCode;
48}
49
50typedef struct GblStackFrame {
51 GBL_ALIGNAS(64)
52 GblCallRecord record;
53 uint32_t sourceCurrentCaptureDepth;
54 GblObject* pObject;
55 GblContext* pContext;
56 uint32_t stackDepth;
57 GblStackFrame* pPrevFrame;
59
60GBL_EXPORT GblContext* GblObject_findContext(GblObject* pSelf) GBL_NOEXCEPT;
61
62// I think this can all become a tiny macro
63GBL_INLINE GBL_RESULT GBL_CTX_STACK_FRAME_CONSTRUCT(GblStackFrame* pFrame, GblObject* pObject, GBL_RESULT initialResult) GBL_NOEXCEPT {
64 GBL_RESULT result = GBL_RESULT_SUCCESS;
65 GblContext* pContext = GBL_NULL;
66
67 if(pObject) GBL_UNLIKELY {
68 const GblStackFrame* pPrev = GblThread_stackFrameTop(NULL);
69 if(pPrev && pPrev->pObject == pObject) GBL_LIKELY {
70 pContext = pPrev->pContext;
71 } else GBL_UNLIKELY {
72 pContext = GblObject_findContext(pObject);
73 }
74 }
75
76 if(!pContext) GBL_LIKELY {
77 pContext = GblThread_context(NULL);
78 }
79
80 pFrame->record.srcLocation.pFile = GBL_NULL;
81 pFrame->record.srcLocation.pFunc = GBL_NULL;
82 pFrame->record.result = initialResult;
83 pFrame->stackDepth = 0;
84 pFrame->sourceCurrentCaptureDepth = 0;
85 pFrame->pObject = pObject;
86 pFrame->pContext = pContext;
87 pFrame->pPrevFrame = NULL;
88 return result;
89}
90
91#ifdef __cplusplus
92}
93#endif
94
95
96#endif // GIMBAL_CALL_STACK_H