1 /*
2
3 Package: dyncall
4 Library: test
5 File: test/plain/test_structs.c
6 Description:
7 License:
8
9 Copyright (c) 2010-2015 Olivier Chafik <olivier.chafik@gmail.com>
10 2019 Tassilo Philipp <tphilipp@potion-studios.com>
11
12 Permission to use, copy, modify, and distribute this software for any
13 purpose with or without fee is hereby granted, provided that the above
14 copyright notice and this permission notice appear in all copies.
15
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
24 */
25
26
27
28
29 #include "../../dyncall/dyncall.h"
30 #include "../../dyncall/dyncall_signature.h"
31 #include "../../dyncall/dyncall_struct.h"
32 #include "../common/platformInit.h"
33
34 #define DC_TEST_STRUCT_SIZE(sig, type, s) { \
35 DCsize expected = sizeof(type), computed = dcStructSize(s);\
36 printf("struct_%s size: expected = %d, computed = %d: %d\n", sig, (int)expected, (int)computed, (expected == computed)); \
37 ret = (expected == computed) && ret; \
38 }
39
40 /* @@@ incomplete and should be makde generally available in dyncall once struct support will make it in */
41 #if defined(DC__OS_Plan9)
42 # define DEFAULT_STRUCT_ALIGNMENT 4
43 #else
44 # define DEFAULT_STRUCT_ALIGNMENT DEFAULT_ALIGNMENT
45 #endif
46
testStructSizes()47 int testStructSizes()
48 {
49 int ret = 1;
50
51 {
52 typedef struct {
53 char a, b;
54 } S;
55
56 size_t size;
57 DCstruct* s = dcNewStruct(2, DEFAULT_STRUCT_ALIGNMENT);
58 dcStructField(s, DC_SIGCHAR_CHAR, DEFAULT_ALIGNMENT, 1);
59 dcStructField(s, DC_SIGCHAR_CHAR, DEFAULT_ALIGNMENT, 1);
60 dcCloseStruct(s);
61
62 DC_TEST_STRUCT_SIZE("cc", S, s);
63 dcFreeStruct(s);
64 }
65 {
66 typedef struct {
67 char a, b, c;
68 } S;
69
70 size_t size;
71 DCstruct* s = dcNewStruct(3, DEFAULT_STRUCT_ALIGNMENT);
72 dcStructField(s, DC_SIGCHAR_CHAR, DEFAULT_ALIGNMENT, 1);
73 dcStructField(s, DC_SIGCHAR_CHAR, DEFAULT_ALIGNMENT, 1);
74 dcStructField(s, DC_SIGCHAR_CHAR, DEFAULT_ALIGNMENT, 1);
75 dcCloseStruct(s);
76
77 DC_TEST_STRUCT_SIZE("ccc", S, s);
78 dcFreeStruct(s);
79 }
80 {
81 typedef struct {
82 char a;
83 short b;
84 } S;
85
86 size_t size;
87 DCstruct* s = dcNewStruct(2, DEFAULT_STRUCT_ALIGNMENT);
88 dcStructField(s, DC_SIGCHAR_CHAR, DEFAULT_ALIGNMENT, 1);
89 dcStructField(s, DC_SIGCHAR_SHORT, DEFAULT_ALIGNMENT, 1);
90 dcCloseStruct(s);
91
92 DC_TEST_STRUCT_SIZE("cs", S, s);
93 dcFreeStruct(s);
94 }
95 {
96 typedef struct {
97 double a, b, c, d;
98 } S;
99
100 size_t size;
101 DCstruct* s = dcNewStruct(4, DEFAULT_STRUCT_ALIGNMENT);
102 dcStructField(s, DC_SIGCHAR_DOUBLE, DEFAULT_ALIGNMENT, 1);
103 dcStructField(s, DC_SIGCHAR_DOUBLE, DEFAULT_ALIGNMENT, 1);
104 dcStructField(s, DC_SIGCHAR_DOUBLE, DEFAULT_ALIGNMENT, 1);
105 dcStructField(s, DC_SIGCHAR_DOUBLE, DEFAULT_ALIGNMENT, 1);
106 dcCloseStruct(s);
107
108 DC_TEST_STRUCT_SIZE("dddd", S, s);
109 dcFreeStruct(s);
110 }
111 {
112 typedef struct {
113 char a, b;
114 void* p[3];
115 } S;
116
117 size_t size;
118 DCstruct* s = dcNewStruct(3, DEFAULT_STRUCT_ALIGNMENT);
119 dcStructField(s, DC_SIGCHAR_CHAR, DEFAULT_ALIGNMENT, 1);
120 dcStructField(s, DC_SIGCHAR_CHAR, DEFAULT_ALIGNMENT, 1);
121 dcStructField(s, DC_SIGCHAR_POINTER, DEFAULT_ALIGNMENT, 3);
122 dcCloseStruct(s);
123
124 DC_TEST_STRUCT_SIZE("cc[ppp]", S, s);
125 dcFreeStruct(s);
126 }
127 {
128 typedef struct {
129 short a;
130 struct {
131 char a, b;
132 void* p[3];
133 } sub;
134 short b;
135 } S;
136
137 size_t size;
138 DCstruct* s = dcNewStruct(3, DEFAULT_STRUCT_ALIGNMENT);
139 dcStructField(s, DC_SIGCHAR_SHORT, DEFAULT_ALIGNMENT, 1);
140 dcSubStruct(s, 3, DEFAULT_STRUCT_ALIGNMENT, 1);
141 dcStructField(s, DC_SIGCHAR_CHAR, DEFAULT_ALIGNMENT, 1);
142 dcStructField(s, DC_SIGCHAR_CHAR, DEFAULT_ALIGNMENT, 1);
143 dcStructField(s, DC_SIGCHAR_POINTER, DEFAULT_ALIGNMENT, 3);
144 dcCloseStruct(s);
145 dcStructField(s, DC_SIGCHAR_SHORT, DEFAULT_ALIGNMENT, 1);
146 dcCloseStruct(s);
147
148 DC_TEST_STRUCT_SIZE("s{cc[ppp]}s", S, s);
149 dcFreeStruct(s);
150 }
151
152 #define TEST_MONO_STRUCT(sig, type, sigchar) \
153 { \
154 typedef struct { \
155 type v; \
156 } S; \
157 \
158 DCstruct* s = dcNewStruct(1, DEFAULT_STRUCT_ALIGNMENT); \
159 dcStructField(s, sigchar, DEFAULT_ALIGNMENT, 1); \
160 dcCloseStruct(s); \
161 \
162 DC_TEST_STRUCT_SIZE(sig, S, s); \
163 dcFreeStruct(s); \
164 }
165
166 TEST_MONO_STRUCT("c", char, DC_SIGCHAR_CHAR); // 4 on plan 9 |
167 TEST_MONO_STRUCT("C", unsigned char, DC_SIGCHAR_UCHAR); // 4 on plan 9 |
168 TEST_MONO_STRUCT("s", short, DC_SIGCHAR_SHORT); // 4 on plan 9 | minimal size of a struct, period?
169 TEST_MONO_STRUCT("S", unsigned short, DC_SIGCHAR_USHORT); // 4 on plan 9 |
170 TEST_MONO_STRUCT("i", int, DC_SIGCHAR_INT);
171 TEST_MONO_STRUCT("I", unsigned int, DC_SIGCHAR_UINT);
172 TEST_MONO_STRUCT("j", long, DC_SIGCHAR_LONG);
173 TEST_MONO_STRUCT("J", unsigned long, DC_SIGCHAR_ULONG);
174 TEST_MONO_STRUCT("l", long long, DC_SIGCHAR_LONGLONG);
175 TEST_MONO_STRUCT("L", unsigned long long, DC_SIGCHAR_ULONGLONG);
176 TEST_MONO_STRUCT("p", void*, DC_SIGCHAR_POINTER);
177 TEST_MONO_STRUCT("f", float, DC_SIGCHAR_FLOAT);
178 TEST_MONO_STRUCT("d", double, DC_SIGCHAR_DOUBLE);
179
180 return ret;
181 }
182
183
184
185 typedef struct
186 {
187 char a, b, c;
188 } FewValues;
189
sum_FewValues(FewValues values)190 double sum_FewValues(FewValues values)
191 {
192 printf("sum_FewValues(a = %d, b = %d, c = %d)\n", (int)values.a, (int)values.b, (int)values.c);
193 return ((double)values.a) + ((double)values.b) + ((double)values.c);
194 }
195
196
197 typedef struct
198 {
199 char a, b;
200 double p[10];
201 } SomeValues;
202
sum_SomeValues(SomeValues values)203 double sum_SomeValues(SomeValues values)
204 {
205 return ((double)values.a) + ((double)values.b) + values.p[0] + values.p[1] + values.p[2];
206 }
207
208
209 /*int testCallStructs()
210 {
211 int ret = 1;
212
213 DCCallVM* pc = dcNewCallVM(4096);
214 {
215 FewValues values;
216 double calledSum, expectedSum;
217 DCstruct* s = dcNewStruct(3, DEFAULT_STRUCT_ALIGNMENT);
218 dcStructField(s, DC_SIGCHAR_CHAR, DEFAULT_ALIGNMENT, 1);
219 dcStructField(s, DC_SIGCHAR_CHAR, DEFAULT_ALIGNMENT, 1);
220 dcStructField(s, DC_SIGCHAR_CHAR, DEFAULT_ALIGNMENT, 1);
221 dcCloseStruct(s);
222
223 DC_TEST_STRUCT_SIZE("ccc", FewValues, s);
224
225 values.a = 1;
226 values.b = 2;
227 values.c = 3;
228
229 dcMode(pc, DC_CALL_C_DEFAULT);
230 dcReset(pc);
231 printf("BEFORE dcArgStruct\n");
232 dcArgStruct(pc, s, &values);
233 printf("AFTER dcArgStruct\n");
234 calledSum = dcCallDouble(pc, (DCpointer)&sum_FewValues);
235 expectedSum = sum_FewValues(values);
236
237 DC_TEST_INT_EQUAL(expectedSum, calledSum);
238 dcFreeStruct(s);
239 }
240 {
241 SomeValues values;
242 double calledSum, expectedSum;
243 DCstruct* s = dcNewStruct(3, DEFAULT_STRUCT_ALIGNMENT);
244 dcStructField(s, DC_SIGCHAR_CHAR, DEFAULT_ALIGNMENT, 1);
245 dcStructField(s, DC_SIGCHAR_CHAR, DEFAULT_ALIGNMENT, 1);
246 dcStructField(s, DC_SIGCHAR_DOUBLE, DEFAULT_ALIGNMENT, 10);
247 dcCloseStruct(s);
248
249 DC_TEST_STRUCT_SIZE("ccd", SomeValues, s);
250
251 values.a = 1;
252 values.b = 2;
253 values.p[0] = 10;
254 values.p[1] = 11;
255 values.p[2] = 12;
256
257 dcMode(pc, DC_CALL_C_DEFAULT);
258 dcReset(pc);
259 dcArgStruct(pc, s, &values);
260 calledSum = dcCallDouble(pc, (DCpointer) &sum_SomeValues);
261 expectedSum = sum_SomeValues(values);
262
263 DC_TEST_INT_EQUAL(expectedSum, calledSum);
264 dcFreeStruct(s);
265 }
266
267 dcFree(pc);
268
269 return ret;
270 }*/
271
272