Mercurial > pub > dyncall > dyncall
comparison test/suite_aggrs/mk-cases.lua @ 482:0f3b6898078d
suite_aggrs (still ahead of checked in version of dyncall, sorry):
- renaming struct -> aggr
- added knobs to:
* control struct packing
* whether to test immutability of aggr-by-val params
* how to copy aggrs (field by field or via = op (which might do a memcpy and thus copy padding garbage, also))
- some macros to reduce file sizes of generated cases
- setting default misalignment to 1
author | Tassilo Philipp |
---|---|
date | Wed, 16 Mar 2022 16:27:50 +0100 |
parents | 653b65580cb4 |
children |
comparison
equal
deleted
inserted
replaced
481:0fc22b5feac7 | 482:0f3b6898078d |
---|---|
1 require"config" | |
1 require"math" | 2 require"math" |
2 local max = math.max | 3 local max_numargs = 0 |
3 local maxargs = 0 | |
4 | 4 |
5 local aggrs = { } | 5 local aggrs = { } |
6 local seen_aggrs = { } | 6 local seen_aggrs = { } |
7 | 7 |
8 | 8 |
64 end | 64 end |
65 | 65 |
66 -- no nesting (= actual func args), generate case code | 66 -- no nesting (= actual func args), generate case code |
67 if n_nest == 0 then | 67 if n_nest == 0 then |
68 h[#h+1] = canon_type(ch) | 68 h[#h+1] = canon_type(ch) |
69 -- aggregate types (more than one char) need copying via a func | 69 -- aggregate types have more than one |
70 if #h[#h] > 1 then | 70 if #h[#h] > 1 then |
71 t[#t+1] = 'f_cp'..h[#h]:sub(8)..'(V_a['..pos.."],&"..name..");" | 71 if aggrcpsimple then |
72 t[#t+1] = '*('..h[#h]..'*)V_a['..pos.."]="..name..";" | |
73 else | |
74 t[#t+1] = 'f_cp'..h[#h]:sub(8)..'(V_a['..pos.."],&"..name..");" | |
75 end | |
76 if aggrmutabletest then | |
77 t[#t] = t[#t]..'memset(&'..name..',0,sizeof('..name..'));' | |
78 end | |
72 else | 79 else |
73 t[#t+1] = "V_"..ch.."["..pos.."]="..name..";" | 80 t[#t+1] = "V_"..ch.."["..pos.."]="..name..";" |
74 end | 81 end |
75 | 82 |
76 -- is return type or func arg? | 83 -- is return type or func arg? |
85 | 92 |
86 pos = pos + 1 | 93 pos = pos + 1 |
87 end | 94 end |
88 end | 95 end |
89 end | 96 end |
90 maxargs = max(maxargs, pos-1) | 97 max_numargs = math.max(max_numargs, pos-1) |
91 h[#h] = "){" | 98 h[#h] = "){" |
92 if #h[6] == 1 then | 99 if #h[6] == 1 then |
93 t[#t+1] = "ret_"..h[6].."("..(pos-1)..")}\n" | 100 t[#t+1] = "ret_"..h[6].."("..(pos-1)..")}\n" |
94 else | 101 else |
95 t[#t+1] = "ret_a("..(pos-1)..","..h[6]..")}\n" | 102 t[#t+1] = "ret_a("..(pos-1)..","..h[6]..")}\n" |
150 agg_sigs [#agg_sigs + 1] = k | 157 agg_sigs [#agg_sigs + 1] = k |
151 agg_names[#agg_names + 1] = at:sub(8) | 158 agg_names[#agg_names + 1] = at:sub(8) |
152 | 159 |
153 -- aggregate def | 160 -- aggregate def |
154 io.write('/* '..k..' */\n') | 161 io.write('/* '..k..' */\n') |
162 if aggrpacking ~= 0 then | |
163 local pack = aggrpacking | |
164 if pack < 0 then | |
165 pack = math.floor(math.pow(2,math.floor(math.log(math.random(math.abs(pack)),2)))) | |
166 end | |
167 io.write('#pragma pack(push,'..pack..')\n') | |
168 end | |
169 | |
155 io.write(at..' { ') | 170 io.write(at..' { ') |
156 for i = 1, #am, 2 do | 171 for i = 1, #am, 2 do |
157 io.write(am[i]..' '..am[i+1]..'; ') | 172 io.write(am[i]..' '..am[i+1]..'; ') |
158 end | 173 end |
159 io.write("};\n") | 174 io.write("};\n") |
175 | |
176 if aggrpacking ~= 0 then | |
177 io.write('#pragma pack(pop)\n') | |
178 end | |
160 | 179 |
161 -- aggregate cp and cmp funcs | 180 -- aggregate cp and cmp funcs |
162 s = { | 181 s = { |
163 'void f_cp'..at:sub(8)..'('..at..' *x, const '..at..' *y) { ', | 182 'void f_cp'..at:sub(8)..'('..at..' *x, const '..at..' *y) { ', |
164 'int f_cmp'..at:sub(8)..'(const '..at..' *x, const '..at..' *y) { return ' | 183 'int f_cmp'..at:sub(8)..'(const '..at..' *x, const '..at..' *y) { return ' |
165 } | 184 } |
166 o = { '=', '==', 'f_cp', 'f_cmp', '; ', ' && ', '', '1' } | 185 o = { '=', '==', 'f_cp', 'f_cmp', '; ', ' && ', '', '1' } |
167 for t = 1, 2 do | 186 for t = 1, 2 do |
168 io.write(s[t]) | 187 if t ~= 1 or aggrcpsimple == false then |
169 local b = {} | 188 io.write(s[t]) |
170 for i = 1, #am, 2 do | 189 local b = {} |
171 local m = split_array_decl(am[i+1]) | 190 for i = 1, #am, 2 do |
172 local fmt = '' | 191 local m = split_array_decl(am[i+1]) |
173 if m[2] ~= nil then -- need array suffixes? | 192 local fmt = '' |
174 fmt = '[%d]' | 193 if m[2] ~= nil then -- need array suffixes? |
175 else | 194 fmt = '[%d]' |
176 m[2] = 1 | |
177 end | |
178 | |
179 for j = 1, m[2] do | |
180 name = m[1]..string.format(fmt, j-1) | |
181 if string.match(am[i], ' ') then -- aggregate canonical types contain at least one space | |
182 b[#b+1] = o[t+2]..am[i]:sub(8)..'(&x->'..name..', &y->'..name..')' | |
183 else | 195 else |
184 b[#b+1] = 'x->'..name..' '..o[t]..' y->'..name | 196 m[2] = 1 |
185 end | 197 end |
186 end | 198 |
187 end | 199 for j = 1, m[2] do |
188 if #b == 0 then -- to handle empty aggregates | 200 name = m[1]..string.format(fmt, j-1) |
189 b[1] = o[t+6] | 201 if string.match(am[i], ' ') then -- aggregate canonical types contain at least one space |
190 end | 202 b[#b+1] = o[t+2]..am[i]:sub(8)..'(&x->'..name..', &y->'..name..')' |
191 io.write(table.concat(b,o[t+4]).."; };\n") | 203 else |
204 b[#b+1] = 'x->'..name..' '..o[t]..' y->'..name | |
205 end | |
206 end | |
207 end | |
208 if #b == 0 then -- to handle empty aggregates | |
209 b[1] = o[t+6] | |
210 end | |
211 io.write(table.concat(b,o[t+4]).."; };\n") | |
212 end | |
192 end | 213 end |
193 | 214 |
194 -- convenient dcnewstruct helper funcs | 215 -- convenient dcnewstruct helper funcs |
195 io.write('DCstruct* f_touchdcst'..at:sub(8)..'() {\n\tstatic DCstruct* at = NULL;\n\tif(!at) {\n\t\tat = dcNewStruct('..(#am>>1)..', sizeof('..at..'), DC_TRUE);\n\t\t') | 216 io.write('DCaggr* f_touchdcst'..at:sub(8)..'() {\n\tstatic DCaggr* at = NULL;\n\tif(!at) {\n\t\tat = dcNewAggr('..(#am>>1)..', sizeof('..at..'), DC_TRUE);\n\t\t') |
196 for i = 1, #am, 2 do | 217 for i = 1, #am, 2 do |
197 local m = split_array_decl(am[i+1]) | 218 local m = split_array_decl(am[i+1]) |
198 if m[2] == nil then -- need array suffixes? | 219 if m[2] == nil then -- need array suffixes? |
199 m[2] = 1 | 220 m[2] = 1 |
200 end | 221 end |
201 if string.match(am[i], ' ') then -- aggregate canonical types contain at least one space | 222 if string.match(am[i], ' ') then -- aggregate canonical types contain at least one space |
202 io.write('dcStructField(at, DC_SIGCHAR_STRUCT, offsetof('..at..', '..m[1]..'), '..m[2]..', f_touchdcst'..am[i]:sub(8)..'());\n\t\t') | 223 --io.write('dcAggrField(at, DC_SIGCHAR_AGGREGATE, offsetof('..at..', '..m[1]..'), '..m[2]..', f_touchdcst'..am[i]:sub(8)..'());\n\t\t') |
224 io.write("AFa("..at..','..m[1]..','..m[2]..','..am[i]:sub(8)..')\n\t\t') | |
203 else | 225 else |
204 io.write("dcStructField(at, '"..am[i].."', offsetof("..at..', '..m[1]..'), '..m[2]..');\n\t\t') | 226 --io.write("dcAggrField(at, '"..am[i].."', offsetof("..at..', '..m[1]..'), '..m[2]..');\n\t\t') |
205 end | 227 io.write("AF('"..am[i].."',"..at..','..m[1]..','..m[2]..')\n\t\t') |
206 end | 228 end |
207 io.write("dcCloseStruct(at);\n\t}\n\treturn at;\n};\n") | 229 end |
230 io.write("dcCloseAggr(at);\n\t}\n\treturn at;\n};\n") | |
208 end | 231 end |
209 | 232 |
210 -- make table.concat work | 233 -- make table.concat work |
211 if #agg_names > 0 then | 234 if #agg_names > 0 then |
212 table.insert(agg_names, 1, '') | 235 table.insert(agg_names, 1, '') |
217 io.write(mksigtab(sigtab)) | 240 io.write(mksigtab(sigtab)) |
218 io.write('const char* G_agg_sigs[] = {\n\t"'..table.concat(agg_sigs, '",\n\t"')..'"\n};\n') | 241 io.write('const char* G_agg_sigs[] = {\n\t"'..table.concat(agg_sigs, '",\n\t"')..'"\n};\n') |
219 io.write('int G_agg_sizes[] = {\n\t'..table.concat(agg_sizes, ',\n\t')..'\n};\n') | 242 io.write('int G_agg_sizes[] = {\n\t'..table.concat(agg_sizes, ',\n\t')..'\n};\n') |
220 io.write('funptr G_agg_touchdcstfuncs[] = {'..string.sub(table.concat(agg_names, ',\n\t(funptr)&f_touchdcst'),2)..'\n};\n') | 243 io.write('funptr G_agg_touchdcstfuncs[] = {'..string.sub(table.concat(agg_names, ',\n\t(funptr)&f_touchdcst'),2)..'\n};\n') |
221 io.write('funptr G_agg_cmpfuncs[] = {'..string.sub(table.concat(agg_names, ',\n\t(funptr)&f_cmp'),2)..'\n};\n') | 244 io.write('funptr G_agg_cmpfuncs[] = {'..string.sub(table.concat(agg_names, ',\n\t(funptr)&f_cmp'),2)..'\n};\n') |
222 io.write("int G_maxargs = "..maxargs..";\n") | 245 io.write("int G_maxargs = "..max_numargs..";\n") |
223 end | 246 end |
224 | 247 |
248 math.randomseed(seed) | |
225 mkall() | 249 mkall() |
226 | 250 |