annotate dyncall/dyncall_struct.c @ 357:d982a00c2177

- PPC64 asm syntax fix, specifying explicitly comparison mode for cmpi (newer toolchains complain, older ones took optional field of instruction which happened to be same value)
author Tassilo Philipp
date Tue, 25 Feb 2020 18:16:13 +0100
parents ee2b6e54b074
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
1 /*
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
2
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
3 Package: dyncall
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
4 Library: dyncall
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
5 File: dyncall/dyncall_struct.c
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
6 Description: C interface to compute struct size
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
7 License:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
8
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
9 Copyright (c) 2010-2015 Olivier Chafik <olivier.chafik@centraliens.net>
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
10
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
11 Permission to use, copy, modify, and distribute this software for any
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
12 purpose with or without fee is hereby granted, provided that the above
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
13 copyright notice and this permission notice appear in all copies.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
14
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
15 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
16 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
17 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
18 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
22
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
23 */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
24
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
25
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
26
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
27 #include "dyncall.h"
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
28 #include "dyncall_signature.h"
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
29 #include "dyncall_struct.h"
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
30 #include "dyncall_alloc.h"
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
31 #include <stdio.h>
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
32 #include <assert.h>
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
33
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
34
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
35 DCstruct* dcNewStruct(DCsize fieldCount, DCint alignment)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
36 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
37 DCstruct* s = (DCstruct*)dcAllocMem(sizeof(DCstruct));
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
38 s->pCurrentStruct = s;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
39 s->pLastStruct = NULL;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
40 s->nextField = 0;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
41 s->fieldCount = fieldCount;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
42 s->alignment = alignment;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
43 s->size = 0;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
44 s->pFields = (DCfield*)dcAllocMem(fieldCount * sizeof(DCfield));
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
45 return s;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
46 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
47
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
48
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
49 void dcStructField(DCstruct* s, DCint type, DCint alignment, DCsize arrayLength)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
50 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
51 DCfield *f;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
52 if (type == DC_SIGCHAR_STRING) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
53 assert(!"Use dcSubStruct instead !!!");
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
54 return;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
55 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
56 assert(s && s->pCurrentStruct);
338
ee2b6e54b074 - minor refactoring for clarity
Tassilo Philipp
parents: 0
diff changeset
57 assert(s->pCurrentStruct->nextField < (DCint)s->pCurrentStruct->fieldCount);
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
58 f = s->pCurrentStruct->pFields + (s->pCurrentStruct->nextField++);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
59 f->type = type;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
60 f->alignment = alignment;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
61 f->arrayLength = arrayLength;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
62 f->pSubStruct = NULL;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
63 switch (type) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
64 case DC_SIGCHAR_BOOL: f->size = sizeof(DCbool); break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
65 case DC_SIGCHAR_CHAR:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
66 case DC_SIGCHAR_UCHAR: f->size = sizeof(DCchar); break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
67 case DC_SIGCHAR_SHORT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
68 case DC_SIGCHAR_USHORT: f->size = sizeof(DCshort); break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
69 case DC_SIGCHAR_INT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
70 case DC_SIGCHAR_UINT: f->size = sizeof(DCint); break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
71 case DC_SIGCHAR_LONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
72 case DC_SIGCHAR_ULONG: f->size = sizeof(DClong); break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
73 case DC_SIGCHAR_LONGLONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
74 case DC_SIGCHAR_ULONGLONG: f->size = sizeof(DClonglong); break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
75 case DC_SIGCHAR_FLOAT: f->size = sizeof(DCfloat); break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
76 case DC_SIGCHAR_DOUBLE: f->size = sizeof(DCdouble); break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
77 case DC_SIGCHAR_POINTER:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
78 case DC_SIGCHAR_STRING: f->size = sizeof(DCpointer); break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
79 default: assert(0);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
80 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
81 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
82
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
83
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
84 void dcSubStruct(DCstruct* s, DCsize fieldCount, DCint alignment, DCsize arrayLength)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
85 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
86 DCfield *f = s->pCurrentStruct->pFields + (s->pCurrentStruct->nextField++);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
87 f->type = DC_SIGCHAR_STRUCT;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
88 f->arrayLength = arrayLength;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
89 f->alignment = alignment;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
90 f->pSubStruct = dcNewStruct(fieldCount, alignment);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
91 f->pSubStruct->pLastStruct = s->pCurrentStruct;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
92 s->pCurrentStruct = f->pSubStruct;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
93 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
94
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
95
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
96 static void dcAlign(DCsize *size, DCsize alignment)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
97 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
98 DCsize mod = (*size) % alignment;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
99 if (mod) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
100 DCsize rest = alignment - mod;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
101 (*size) += rest;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
102 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
103 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
104
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
105
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
106 static void dcComputeStructSize(DCstruct* s)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
107 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
108 DCsize i;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
109 assert(s);
338
ee2b6e54b074 - minor refactoring for clarity
Tassilo Philipp
parents: 0
diff changeset
110
ee2b6e54b074 - minor refactoring for clarity
Tassilo Philipp
parents: 0
diff changeset
111 /* compute field sizes and alignments, recurse if needed */
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
112 for (i = 0; i < s->fieldCount; i++) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
113 DCfield *f = s->pFields + i;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
114 DCsize fieldAlignment;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
115 if (f->type == DC_SIGCHAR_STRUCT) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
116 dcComputeStructSize(f->pSubStruct);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
117 f->size = f->pSubStruct->size;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
118 fieldAlignment = f->pSubStruct->alignment;
338
ee2b6e54b074 - minor refactoring for clarity
Tassilo Philipp
parents: 0
diff changeset
119 } else
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
120 fieldAlignment = f->size;
338
ee2b6e54b074 - minor refactoring for clarity
Tassilo Philipp
parents: 0
diff changeset
121
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
122 if (!f->alignment)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
123 f->alignment = fieldAlignment;
338
ee2b6e54b074 - minor refactoring for clarity
Tassilo Philipp
parents: 0
diff changeset
124
ee2b6e54b074 - minor refactoring for clarity
Tassilo Philipp
parents: 0
diff changeset
125 /* if field alignment > struct alignment, choose former */
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
126 if (f->alignment > s->alignment)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
127 s->alignment = f->alignment;
338
ee2b6e54b074 - minor refactoring for clarity
Tassilo Philipp
parents: 0
diff changeset
128
ee2b6e54b074 - minor refactoring for clarity
Tassilo Philipp
parents: 0
diff changeset
129 /* if array, it's x times the size */
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
130 f->size *= f->arrayLength;
338
ee2b6e54b074 - minor refactoring for clarity
Tassilo Philipp
parents: 0
diff changeset
131
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
132 /*printf("FIELD %d, size = %d, alignment = %d\n", (int)i, (int)f->size, (int)f->alignment);@@@*/
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
133 }
338
ee2b6e54b074 - minor refactoring for clarity
Tassilo Philipp
parents: 0
diff changeset
134
ee2b6e54b074 - minor refactoring for clarity
Tassilo Philipp
parents: 0
diff changeset
135 /* compute overall struct size */
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
136 for (i = 0; i < s->fieldCount; i++) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
137 DCfield *f = s->pFields + i;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
138 dcAlign(&s->size, f->alignment);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
139 s->size += f->size;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
140 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
141 dcAlign(&s->size, s->alignment);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
142
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
143 /*printf("STRUCT size = %d, alignment = %d\n", (int)s->size, (int)s->alignment);@@@*/
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
144 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
145
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
146
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
147 void dcCloseStruct(DCstruct* s)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
148 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
149 assert(s);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
150 assert(s->pCurrentStruct);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
151 assert(s->pCurrentStruct->nextField == s->pCurrentStruct->fieldCount);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
152 if (!s->pCurrentStruct->pLastStruct) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
153 dcComputeStructSize(s->pCurrentStruct);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
154 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
155 s->pCurrentStruct = s->pCurrentStruct->pLastStruct;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
156 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
157
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
158
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
159 void dcFreeStruct(DCstruct* s)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
160 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
161 DCsize i;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
162 assert(s);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
163 for (i = 0; i < s->fieldCount; i++) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
164 DCfield *f = s->pFields + i;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
165 if (f->type == DC_SIGCHAR_STRUCT)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
166 dcFreeStruct(f->pSubStruct);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
167 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
168 free(s->pFields);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
169 free(s);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
170 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
171
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
172
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
173 DCsize dcStructSize(DCstruct* s)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
174 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
175 assert(!s->pCurrentStruct && "Struct was not closed");
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
176 return s->size;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
177 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
178
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
179 DCsize dcStructAlignment(DCstruct* s)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
180 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
181 assert(!s->pCurrentStruct && "Struct was not closed");
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
182 return s->alignment;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
183 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
184
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
185
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
186 void dcArgStructUnroll(DCCallVM* vm, DCstruct* s, DCpointer value)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
187 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
188 DCsize i;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
189 /*printf("UNROLLING STRUCT !\n");@@@*/
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
190 assert(s && value);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
191 for (i = 0; i < s->fieldCount; i++) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
192 DCfield *f = s->pFields + i;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
193 DCpointer p = (char*)value + f->offset;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
194 switch(f->type) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
195 case DC_SIGCHAR_STRUCT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
196 dcArgStruct(vm, f->pSubStruct, p);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
197 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
198 case DC_SIGCHAR_BOOL:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
199 dcArgBool (vm, *(DCbool*)p);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
200 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
201 case DC_SIGCHAR_CHAR:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
202 case DC_SIGCHAR_UCHAR:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
203 dcArgChar (vm, *(DCchar*)p);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
204 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
205 case DC_SIGCHAR_SHORT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
206 case DC_SIGCHAR_USHORT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
207 dcArgShort (vm, *(DCshort*)p);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
208 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
209 case DC_SIGCHAR_INT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
210 case DC_SIGCHAR_UINT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
211 dcArgInt (vm, *(DCint*)p);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
212 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
213 case DC_SIGCHAR_LONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
214 case DC_SIGCHAR_ULONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
215 dcArgLong (vm, *(DCulong*)p);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
216 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
217 case DC_SIGCHAR_LONGLONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
218 case DC_SIGCHAR_ULONGLONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
219 dcArgLongLong (vm, *(DCulonglong*)p);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
220 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
221 case DC_SIGCHAR_FLOAT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
222 dcArgFloat (vm, *(DCfloat*)p);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
223 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
224 case DC_SIGCHAR_DOUBLE:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
225 dcArgDouble (vm, *(DCdouble*)p);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
226 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
227 case DC_SIGCHAR_POINTER:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
228 case DC_SIGCHAR_STRING:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
229 dcArgPointer (vm, *(DCpointer**)p);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
230 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
231 default:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
232 assert(0);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
233 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
234 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
235 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
236
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
237
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
238 static DCint readInt(const char** ptr)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
239 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
240 return strtol(*ptr, (char**)ptr, 10);/*@@@ enough*/
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
241 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
242
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
243
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
244 DCstruct* dcDefineStruct(const char* signature)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
245 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
246 DCstruct* s;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
247 const char* ptr = signature;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
248 DCint fieldCount = readInt(&ptr);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
249 s = dcNewStruct(fieldCount, DEFAULT_ALIGNMENT);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
250
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
251 while (*ptr) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
252 char type = *(ptr++);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
253 if (type == DC_SIGCHAR_STRUCT) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
254 /*dcSubStruct( @@@*/
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
255 } else {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
256 dcStructField(s, type, DEFAULT_ALIGNMENT, readInt(&ptr));
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
257 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
258 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
259 dcCloseStruct(s);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
260 return s;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
261 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
262