GCC Code Coverage Report


Directory: src/gate/
File: src/gate/tests/gatecore_cpp_platform_test/test_functions.cpp
Date: 2026-08-06 22:46:24
Exec Total Coverage
Lines: 111 113 98.2%
Functions: 26 26 100.0%
Branches: 118 313 37.7%

Line Branch Exec Source
1 #include "gate/tests.hpp"
2 #include "gate/functions.hpp"
3 #include "gate/callstacks.hpp"
4
5 using namespace gate;
6
7
2/7
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
6 GATEXX_TEST_UNIT(CallstackTrace)
8 {
9 Callstack::Address addrbuffer[32];
10 4 Result<gate::size_t> traceResult = Callstack::trace(addrbuffer, sizeof(addrbuffer) / sizeof(addrbuffer[0]));
11
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2 if (traceResult.hasError() && (traceResult.error() == results::NotSupported))
12 {
13 /* trace feature not support on platform, tests are meaningless */
14 }
15 else
16 {
17
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
2 GATEXX_TEST_REQUIRE(traceResult.hasValue());
18 2 gate::size_t addrbuffer_used = traceResult.value();
19
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
2 GATEXX_TEST_REQUIRE(addrbuffer_used > 0);
20
21
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
4 StringBuilder sb;
22 4 VoidResult printResult = Callstack::print(addrbuffer[0], sb);
23
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
2 GATEXX_TEST_CHECK(!printResult.hasError());
24 }
25 2 }
26
27
28 static int cs_state = 0;
29 static Callstack::Context main_context;
30 static Callstack::Context other_context;
31
32 class GATE_API_LOCAL OtherStackCode : public IRunnable
33 {
34 public:
35 1 void run() override
36 {
37 1 cs_state = 1;
38 1 Callstack::switchTo(other_context, main_context);
39 }
40 };
41
42
2/7
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
6 GATEXX_TEST_UNIT(CallstackRun)
43 {
44
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
4 Callstack cs(4096);
45 2 OtherStackCode otherCode;
46 2 cs_state = 0;
47 4 Result<result_t> result = cs.run(main_context, otherCode);
48
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2 if (result.hasError() && (result.error() == results::NotSupported))
49 {
50 /* stack switching is not supported on this platform, further tests are meaningless*/
51 }
52 else
53 {
54
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
2 GATEXX_TEST_REQUIRE(!result.hasError());
55
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
2 GATEXX_TEST_CHECK(result.value() == results::Ok);
56
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
2 GATEXX_TEST_CHECK(cs_state == 1);
57 }
58 2 }
59
60
61 static int fork_state = 0;
62
63 class GATE_API_LOCAL MainForkCode : public IRunnable
64 {
65 public:
66 Callstack::Anchor anchor;
67
68 1 void run() override
69 {
70
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK(fork_state == 0);
71 1 fork_state = 1;
72 1 Callstack::jumpToBranch(this->anchor);
73 }
74 };
75
76 class GATE_API_LOCAL BranchCode : public IRunnable
77 {
78 public:
79 1 void run() override
80 {
81
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK(fork_state == 1);
82 1 fork_state = 2;
83 1 }
84 };
85
86
2/7
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
6 GATEXX_TEST_UNIT(CallstackFork)
87 {
88 4 MainForkCode maincode;
89 2 BranchCode branchcode;
90 2 fork_state = 0;
91 4 VoidResult result = Callstack::fork(maincode.anchor, maincode, branchcode);
92
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
2 GATEXX_TEST_CHECK(!result.hasError());
93
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
2 GATEXX_TEST_CHECK(fork_state == 2);
94 2 }
95
96
97 1 static int test_func_sargs(signed char a, short b, int c, long d, long long e)
98 {
99 1 return a + b + c + d + static_cast<int>(e);
100 }
101
102 1 static unsigned int test_func_uargs(unsigned char a, unsigned short b, unsigned int c, unsigned long d, unsigned long long e)
103 {
104 1 return a + b + c + d + static_cast<unsigned>(e);
105 }
106
107 /*
108 static int test_func_float(float a, double b, void* c)
109 {
110 double* const ptr = static_cast<double*>(c);
111 GATEXX_TEST_CHECK(ptr != NULL);
112 if(ptr)
113 {
114 *ptr = a + b;
115 return static_cast<int>(*ptr);
116 }
117 return 0;
118 }
119 */
120
121 static int global_test_data1 = 123;
122 static int global_test_data2 = 234;
123 static int global_test_data3 = 345;
124
125 1 static int test_func_pointer(void* ptr1, void* ptr2, void* ptr3)
126 {
127
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK(ptr1 == &global_test_data1);
128
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK(ptr2 == &global_test_data2);
129
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK(ptr3 == &global_test_data3);
130
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 return (ptr1 == &global_test_data1) && (ptr2 == &global_test_data2) && (ptr3 == &global_test_data3)
131
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 ? 777 : 0;
132 }
133
134 struct byte12struct
135 {
136 char items[12];
137 };
138
139 1 static int test_func_struct(struct byte12struct blob)
140 {
141
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK_EQUAL(blob.items[ 0], 'H');
142
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK_EQUAL(blob.items[ 1], 'e');
143
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK_EQUAL(blob.items[ 2], 'l');
144
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK_EQUAL(blob.items[ 3], 'l');
145
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK_EQUAL(blob.items[ 4], 'o');
146
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK_EQUAL(blob.items[ 5], ' ');
147
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK_EQUAL(blob.items[ 6], 'W');
148
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK_EQUAL(blob.items[ 7], 'o');
149
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK_EQUAL(blob.items[ 8], 'r');
150
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK_EQUAL(blob.items[ 9], 'l');
151
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK_EQUAL(blob.items[10], 'd');
152
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK_EQUAL(blob.items[11], '\0');
153 1 return 12;
154 }
155
156
2/7
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
6 GATEXX_TEST_UNIT(GenericFunction)
157 {
158 { // signed int
159 FunctionArgument args[5] = {
160 static_cast<signed char>(1),
161 static_cast<signed short>(2),
162 4 static_cast<signed int>(3),
163 static_cast<signed long>(4),
164 static_cast<signed long long>(5)
165
2/4
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
14 };
166
167
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
4 FunctionArgument retval = Function::invokeGeneric((gate_funcptr_t)&test_func_sargs, 0, args, 5);
168
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 retval.getType();
169
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 int iretval = *static_cast<int const*>(retval.getValuePtr());
170
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
2 GATEXX_TEST_CHECK_EQUAL(iretval, 15);
171 }
172
173 { // unsigned int
174 FunctionArgument args[5] = {
175 static_cast<unsigned char>(1),
176 static_cast<unsigned short>(2),
177 static_cast<unsigned int>(3),
178 static_cast<unsigned long>(4),
179 static_cast<unsigned long long>(5)
180
2/4
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
14 };
181
182
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
4 FunctionArgument retval = Function::invokeGeneric((gate_funcptr_t)&test_func_uargs, 0, args, 5);
183
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 retval.getType();
184
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 int iretval = *static_cast<int const*>(retval.getValuePtr());
185
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
2 GATEXX_TEST_CHECK_EQUAL(iretval, 15);
186
187 // test copy construction
188 4 FunctionArgument t0 = args[0];
189 4 FunctionArgument t1 = args[1];
190 4 FunctionArgument t2 = args[2];
191 4 FunctionArgument t3 = args[3];
192 2 FunctionArgument t4 = args[4];
193 }
194
195 /*
196 // NOTICE: floating point args are not working on register-based calling convention,
197 // tests will fail on X64
198 { // float + ptr
199 double dbl_result = 0.0;
200 FunctionArgument args[3] = {
201 static_cast<double>(1.0),
202 static_cast<float>(2.0),
203 static_cast<void*>(&dbl_result)
204 };
205
206 FunctionArgument retval = Function::invokeGeneric((gate_funcptr_t)&test_func_float, 0, args, 3);
207 int iretval = *static_cast<int const*>(retval.getValuePtr());
208 GATEXX_TEST_CHECK_EQUAL(iretval, 3);
209 }
210 */
211
212 // test generic pointer
213 {
214 FunctionArgument args[3] = {
215 static_cast<void*>(&global_test_data1),
216 static_cast<void*>(&global_test_data2),
217 static_cast<void*>(&global_test_data3)
218
2/4
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
10 };
219
220
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
4 FunctionArgument retval = Function::invokeGeneric((gate_funcptr_t)&test_func_pointer, 0, args, 3);
221
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 int iretval = *static_cast<int const*>(retval.getValuePtr());
222
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
2 GATEXX_TEST_CHECK_EQUAL(iretval, 777);
223 }
224
225 #if !defined(GATE_SYS_WIN)
226 {
227 static char txt[] = "Hello World";
228 4 FunctionArgument arg(txt, sizeof(txt));
229
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
4 FunctionArgument retval = Function::invokeGeneric((gate_funcptr_t)&test_func_struct, 0, &arg, 1);
230
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 int iretval = *static_cast<int const*>(retval.getValuePtr());
231
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
2 GATEXX_TEST_CHECK_EQUAL(iretval, 12);
232 }
233 #endif
234
235 2 }
236
237 class GATE_API_INTERNAL GuardedCodeTarget : public gate::IRunnable, public gate::IQuitable
238 {
239 public:
240 result_t exitResult;
241
242 3 explicit GuardedCodeTarget(result_t exit_result = results::Ok)
243 3 : exitResult(exit_result)
244 {
245 3 }
246
247 6 virtual ~GuardedCodeTarget() noexcept
248 6 {
249 6 }
250
251 3 virtual void run() override
252 {
253
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (this->exitResult == results::UnknownException)
254 {
255 1 throw 123;
256 }
257
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 GATEXX_CHECK_EXCEPTION(this->exitResult);
258 1 }
259
260 1 virtual void quit() override
261 {
262 1 }
263 };
264
265
2/7
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
6 GATEXX_TEST_UNIT(InvokeGuarded)
266 {
267 {
268 4 GuardedCodeTarget noThrowCode(results::Ok);
269
4/14
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 GATEXX_TEST_CHECK_NOTHROW(Function::invokeGuarded(noThrowCode));
270 2 noThrowCode.quit();
271 }
272 {
273 4 GuardedCodeTarget throwCode(results::Failed);
274
5/14
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
4 GATEXX_TEST_CHECK_THROW(Function::invokeGuarded(throwCode));
275 }
276 {
277 4 GuardedCodeTarget foreignCxxThrowCode(results::UnknownException);
278
5/14
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
4 GATEXX_TEST_CHECK_THROW(Function::invokeGuarded(foreignCxxThrowCode));
279 }
280 2 }
281