libGimbal 0.1.0
C17-Based Extended Standard Library and Cross-Language Runtime Framework
Loading...
Searching...
No Matches
gimbal_stack_frame.h
Go to the documentation of this file.
1/*! \file
2 * \brief Stack frame, call record, source capture debug utilities
3 * \ingroup core
4 *
5 * \author Falco Girgis
6 */
7
8#ifndef GIMBAL_CALL_STACK_H
9#define GIMBAL_CALL_STACK_H
10
11#include "../core/gimbal_result.h"
12#include <stdarg.h>
13#include <stdio.h>
14
16
19
20//! Source code context (file, function, line)
21typedef struct GblSourceLocation {
22 const char* pFile; //!< Current Source file
23 const char* pFunc; //!< Current function
24 size_t line; //!< Current line of code
25} GblSourceLocation;
26
27//! Captures a result, its stringified message, and a source context
28typedef struct GblCallRecord {
29 GBL_ALIGNAS(8)
30 //! Error or result message from a previous GblStackFrame.
32 //! Source location where the result + message had been set.
33 GblSourceLocation srcLocation;
34 //! Result code from a previous stack frame
35 GBL_RESULT result;
36} GblCallRecord;
37
38//! Represents a single function's stack frame, from GBL_CTX_BEGIN() to GBL_CTX_END()
39typedef struct GblStackFrame {
40 GBL_ALIGNAS(8)
41 GblCallRecord record;
42 uint32_t sourceCurrentCaptureDepth;
43 GblObject* pObject;
44 GblContext* pContext;
45 uint32_t stackDepth;
46 struct GblStackFrame* pPrevFrame;
47} GblStackFrame;
48
49// ===== Public API =====
50GBL_INLINE void GblCallRecord_construct (GblCallRecord* pRecord,
51 GBL_RESULT resultCode,
52 GblSourceLocation source,
53 const char* pFmt, ...) GBL_NOEXCEPT;
54
55GBL_INLINE GBL_RESULT GblStackFrame_construct (GblStackFrame* pFrame,
56 GblObject* pObject,
57 GBL_RESULT initialResult) GBL_NOEXCEPT;
58
59// ===== Implementation =====
60///\cond
63GBL_EXPORT GblThd* GblThd_current (void) GBL_NOEXCEPT;
64GBL_EXPORT GblContext* GblThd_context (const GblThd* pSelf) GBL_NOEXCEPT;
65GBL_INLINE GblStackFrame* GblThd_stackFrameTop (const GblThd* pSelf) GBL_NOEXCEPT;
66GBL_EXPORT GblContext* GblObject_findContext (GblObject* pSelf) GBL_NOEXCEPT;
67
68GBL_EXPORT GBL_RESULT GblContext_memAlloc_ (GblContext* pSelf,
69 const GblStackFrame* pFrame,
70 size_t size,
71 size_t align,
72 const char* pDbgStr,
73 void** ppData) GBL_NOEXCEPT;
74
75GBL_EXPORT GBL_RESULT GblContext_memRealloc_ (GblContext* pSelf,
76 const GblStackFrame* pFrame,
77 void* pData,
78 size_t newSize,
79 size_t newAlign,
80 void** ppNewData) GBL_NOEXCEPT;
81
82GBL_EXPORT GBL_RESULT GblContext_memFree_ (GblContext* pSelf,
83 const GblStackFrame* pFrame,
84 void* pData) GBL_NOEXCEPT;
85
86GBL_EXPORT GBL_RESULT GblContext_logWrite_ (GblContext* pSelf,
87 const GblStackFrame* pFrame,
88 GblFlags level,
89 const char* pFmt,
90 va_list varArgs) GBL_NOEXCEPT;
91
92GBL_EXPORT GBL_RESULT GblContext_logPush_ (GblContext* pSelf,
93 const GblStackFrame* pFrame) GBL_NOEXCEPT;
94
95GBL_EXPORT GBL_RESULT GblContext_logPop_ (GblContext* pSelf,
96 const GblStackFrame* pFrame,
97 uint32_t count) GBL_NOEXCEPT;
98
99GBL_EXPORT GBL_RESULT GblContext_callRecordSet_ (GblContext* pSelf,
100 const GblStackFrame* pFrame,
101 const GblCallRecord* pRecord) GBL_NOEXCEPT;
102
103///\endcond
104
105GBL_INLINE void GblCallRecord_construct(GblCallRecord* pRecord, GBL_RESULT resultCode, GblSourceLocation source, const char* pFmt, ...) GBL_NOEXCEPT {
106 va_list varArgs;
107 va_start(varArgs, pFmt);
108 pRecord->result = GBL_RESULT_UNKNOWN;
109 pRecord->message[0] = '\0';
111 if(pFmt) GBL_UNLIKELY vsprintf(pRecord->message, pFmt, varArgs);
112 va_end(varArgs);
113 pRecord->srcLocation = source;
114 pRecord->result = resultCode;
115}
116
117GBL_INLINE GBL_RESULT GblStackFrame_construct(GblStackFrame* pFrame, GblObject* pObject, GBL_RESULT initialResult) GBL_NOEXCEPT {
118 GBL_RESULT result = GBL_RESULT_SUCCESS;
119 GblContext* pContext = GBL_NULL;
120
121 if(pObject) GBL_UNLIKELY {
122 const GblStackFrame* pPrev = GblThd_stackFrameTop(NULL);
123 if(pPrev && pPrev->pObject == pObject) GBL_LIKELY {
124 pContext = pPrev->pContext;
125 } else GBL_UNLIKELY {
126 pContext = GblObject_findContext(pObject);
127 }
128 }
129
130 if(!pContext) GBL_LIKELY {
131 pContext = GblThd_context(NULL);
132 }
133
134 pFrame->record.srcLocation.pFile = GBL_NULL;
135 pFrame->record.srcLocation.pFunc = GBL_NULL;
136 pFrame->record.result = initialResult;
137 pFrame->stackDepth = 0;
138 pFrame->sourceCurrentCaptureDepth = 0;
139 pFrame->pObject = pObject;
140 pFrame->pContext = pContext;
141 pFrame->pPrevFrame = NULL;
142 return result;
143}
144
146
147#endif // GIMBAL_CALL_STACK_H
#define GBL_NULL
#define GBL_LIKELY
#define GBL_NOEXCEPT
#define GBL_UNLIKELY
#define GBL_INLINE
#define GBL_DECLS_BEGIN
#define GBL_FORWARD_DECLARE_STRUCT(S)
#define GBL_EXPORT
uint32_t GblFlags
Standard-sized flags type, 32-bits across platforms.
Captures a result, its stringified message, and a source context.
GblSourceLocation srcLocation
Source location where the result + message had been set.
GBL_RESULT result
Result code from a previous stack frame.
GblContext * GblObject_findContext(GblObject *pSelf)
Source code context (file, function, line)
const char * pFile
Current Source file.
const char * pFunc
Current function.
size_t line
Current line of code.
Represents a single function's stack frame, from GBL_CTX_BEGIN() to GBL_CTX_END()