-
Notifications
You must be signed in to change notification settings - Fork 0
/
setup.winxed
434 lines (327 loc) · 11.2 KB
/
setup.winxed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
#! winxed
/*
=head1 NAME
setup.winxed - Python distutils style
=head1 DESCRIPTION
=head2 Functions
=over 4
=item C<main>
run distutils
=cut
*/
function main(var argv) {
using extern distutils;
using template_fill;
using template_clean;
/* ignore first element in argv (program name) */
argv.shift();
register_step_before('build', template_fill);
register_step_after('clean', template_clean);
var conf = load_setup_json();
conf['template_data'] = gen_tmpl_data(conf);
setup(argv:[flat], conf:[flat,named]);
}
/*
=item C<template_fill>
custom distutils build step to replace @var@ patterns in template files with the
appropriate data to create the actual source files
=item C<do_subst>
run a template substitution on one file
=item C<template_clean>
custom distutils clean step to clean up files generated with templates
=cut
*/
function template_fill(var kv[named,slurpy]) {
var templates = kv['template'] ? kv['template'] : {};
var template_data = kv['template_data'] ? kv['template_data'] : [];
for (string tmpl_file in templates) {
string targ_file = templates[tmpl_file];
do_subst(template_data, tmpl_file, targ_file);
}
}
function do_subst(var subst_data, string in_file, string out_file) {
say(in_file);
say(out_file);
var in_fh = open(in_file, 'ro');
var out_fh = open(out_file, 'rw');
while (in_fh) {
var line = in_fh.readline();
for (string tmpl_var in subst_data) {
string search = "@" + tmpl_var + "@";
line.replace(search, subst_data[tmpl_var]);
}
out_fh.puts(line);
}
in_fh.close();
out_fh.close();
}
function template_clean(var kv[named,slurpy]) {
var templates = kv['template'] ? kv['template'] : {};
for (string tmpl_file in templates) {
string targ_file = templates[tmpl_file];
unlink(targ_file, 1:[named('verbose')]);
}
}
/*
=item C<load_setup_json>
read setup.json
=cut
*/
function load_setup_json() {
var file = open('setup.json');
string json_str = file.readall();
file.close();
var json = load_language('data_json');
var promise = json.compile(json_str);
return promise();
}
/*
=item C<gen_tmpl_data>
generate data to be used in templates
=cut
*/
function gen_tmpl_data(var conf) {
var vtable_wrappers = gen_vtable_wrappers(conf['wrapped_vtables']);
var function_wrappers = gen_function_wrappers(conf['wrapped_functions']);
return {
'libjit_iv': pick_iv(),
'libjit_uv': pick_uv(),
'libjit_nv': pick_nv(),
'libjit_has_alloca': 0, // XXX detect this properly
'vtable_wrap_decls': join( "\n", decls( vtable_wrappers ) ),
'vtable_wrap_defns': join( "\n", defns( vtable_wrappers ) ),
'func_wrap_decls': join( "\n", decls( function_wrappers ) ),
'func_wrap_defns': join( "\n", defns( function_wrappers ) )
};
}
/*
=item C<pick_iv>
Pick a libjit type corresponding to Parrot's IV
=item C<pick_uv>
Pick a libjit type corresponding to Parrot's UV
=item C<pick_nv>
Pick a libjit type corresponding to Parrot's NV
=cut
*/
function pick_iv() {
using get_config;
var parrot_config = get_config();
string iv = parrot_config['iv'];
switch (iv) {
case 'short':
return 'jit_type_sys_short';
case 'int':
return 'jit_type_sys_int';
case 'long':
return 'jit_type_sys_long';
case 'long long':
return 'jit_type_sys_longlong';
default:
throw new 'Exception'({
'message': sprintf("Couldn't determine a libjity type for intval of type '%s'", [iv])
});
}
}
function pick_uv() {
using get_config;
var parrot_config = get_config();
string iv = parrot_config['iv'];
switch (iv) {
case 'short':
return 'jit_type_sys_ushort';
case 'int':
return 'jit_type_sys_uint';
case 'long':
return 'jit_type_sys_ulong';
case 'long long':
return 'jit_type_sys_ulonglong';
default:
throw new 'Exception'({
'message':
sprintf("Couldn't determine a libjity type for uintval of type 'unsigned %s'", [iv])
});
}
}
function pick_nv() {
using get_config;
var parrot_config = get_config();
string nv = parrot_config['nv'];
switch (nv) {
case 'float':
return 'jit_type_sys_float';
case 'double':
return 'jit_type_sys_double';
case 'long double':
return 'jit_type_sys_long_double';
default:
throw new 'Exception'({
'message': sprintf("Couldn't determine a libjity type for floatval of type '%s'", [nv])
});
}
}
/*
=item C<decls>
get the declaration portions of the wrappers
=item C<defns>
get the definition portions of the wrappers
=cut
*/
function decls(var wrappers) {
var retv = [];
for (var x in wrappers)
retv.push(x['decl']);
return retv;
}
function defns(var wrappers) {
var retv = [];
for (var x in wrappers)
retv.push(x['defn']);
return retv;
}
/*
=item C<jit_prefix_type>
convert a C type into a libjit type
=cut
*/
function jit_prefix_type(string type) {
if (type == downcase(type))
return 'jit_type_' + type;
else if (type == upcase(type))
return 'JIT_TYPE_' + type;
else
throw new 'Exception'({ "message": "can't jit_prefix_type: inconsistent case" });
}
/*
=item C<gen_vtable_wrappers>
=item C<gen_function_wrappers>
generate C source code to wrap operations for later JIT calling
=cut
*/
function gen_vtable_wrappers(var vtables) {
const string vtable_decl_tmpl =
"static jit_value_t\n" +
"jit__vtable_%s(jit_function_t, jit_value_t, jit_value_t %s);";
const string vtable_defn_tmpl =
"static jit_value_t\n" +
"jit__vtable_%s(jit_function_t f, jit_value_t interp, jit_value_t self %s) {" +
" const int n_args = %d + 2;\n" +
" jit_type_t sig;\n" +
" jit_value_t vtable, method;\n" +
" jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr %s };\n" +
" jit_value_t arg_v[] = { interp, self %s };\n" +
" sig = jit_type_create_signature(jit_abi_cdecl, %s, arg_t, n_args, 1);\n" +
" vtable = jit_insn_load_relative(f, self, offsetof(PMC, vtable), jit_type_void_ptr);\n" +
" method = jit_insn_load_relative(f, vtable, offsetof(VTABLE, %s), jit_type_void_ptr);\n" +
" return jit_insn_call_indirect(f, method, sig, arg_v, n_args, 0);\n" +
"}";
var wrappers = [];
for (string entry_name in vtables) {
var entry_sig = vtables[entry_name];
int n_args = entry_sig[0];
var acc = [];
for (int i = 0; i < n_args; i++)
acc[i] = sprintf(', %s', [jit_prefix_type(entry_sig[0,i])]);
string arg_t = join('', acc);
string ret_t = jit_prefix_type(entry_sig[1]);
acc = [];
for (int i = 0; i < n_args; i++)
acc.push(sprintf(', v%d', [i]));
string arg_v = join('', acc);
acc = [];
for (int i = 0; i < n_args; i++)
acc.push(', jit_value_t');
string arg_decls_t = join('', acc);
acc = [];
for (int i = 0; i < n_args; i++)
acc.push(sprintf(', jit_value_t v%d', [i]));
string arg_decls_v = join('', acc);
wrappers.push({
'decl': sprintf(vtable_decl_tmpl, [entry_name, arg_decls_t]),
'defn': sprintf(vtable_defn_tmpl,
[entry_name, arg_decls_v, n_args, arg_t, arg_v, ret_t, entry_name])
});
}
return wrappers;
}
function gen_function_wrappers(var funcs) {
var wrappers = [];
for (string entry_name in funcs) {
var entry_sig = funcs[entry_name];
var args_sig = entry_sig[0];
int n_args = elements(args_sig);
string func_decl_tmpl;
string func_defn_tmpl;
if (n_args && args_sig[n_args - 1] == '...') {
args_sig.pop();
n_args--;
func_decl_tmpl =
"static jit_value_t\n" +
"jit__%s(jit_function_t %s, jit_type_t *, jit_value_t *, int);\n";
func_defn_tmpl =
"static jit_value_t\n" +
"jit__%s(jit_function_t f %s, jit_type_t *va_t, jit_value_t *va_v, const int va_n) {\n" +
" int i;\n" +
" const int n_args = %d;\n" +
" jit_type_t sig;\n" +
" jit_value_t vtable;\n" +
" jit_type_t arg_t[n_args + va_n];\n" +
" jit_value_t arg_v[n_args + va_n];\n" +
" jit_type_t carg_t[] = { %s };\n" +
" jit_value_t carg_v[] = { %s };\n" +
" for (i = 0; i < n_args; i++) {\n" +
" arg_t[i] = carg_t[i];\n" +
" arg_v[i] = carg_v[i];\n" +
" }\n" +
" for (i = 0; i < va_n; i++) {\n" +
" arg_t[n_args + i] = va_t[i];\n" +
" arg_v[n_args + i] = va_v[i];\n" +
" }\n" +
" sig = jit_type_create_signature(jit_abi_cdecl, %s, arg_t, n_args + va_n, 1);\n" +
" return jit_insn_call_native(f, \"%s\", (void *)&%s, sig, arg_v, n_args + va_n, 0);\n" +
"}\n";
} else {
func_decl_tmpl =
"static jit_value_t\n" +
"jit__%s(jit_function_t %s);\n";
func_defn_tmpl =
"static jit_value_t\n" +
"jit__%s(jit_function_t f %s) {\n" +
" const int n_args = %d;\n" +
" jit_type_t sig;\n" +
" jit_value_t vtable;\n" +
" jit_type_t arg_t[] = { %s };\n" +
" jit_value_t arg_v[] = { %s };\n" +
" sig = jit_type_create_signature(jit_abi_cdecl, %s, arg_t, n_args, 1);\n" +
" return jit_insn_call_native(f, \"%s\", (void *)&%s, sig, arg_v, n_args, 0);\n" +
"}\n";
}
var acc = [];
for (int i = 0; i < n_args; i++)
acc[i] = sprintf('%s', [jit_prefix_type(args_sig[i])]);
string arg_t = join(', ', acc);
string ret_t = jit_prefix_type(entry_sig[1]);
acc = [];
for (int i = 0; i < n_args; i++)
acc.push(sprintf('v%d', [i]));
string arg_v = join(', ', acc);
acc = [];
for (int i = 0; i < n_args; i++)
acc.push(', jit_value_t');
string arg_decls_t = join('', acc);
acc = [];
for (int i = 0; i < n_args; i++)
acc.push(sprintf(', jit_value_t v%d', [i]));
string arg_decls_v = join('', acc);
wrappers.push({
'decl': sprintf(func_decl_tmpl, [entry_name, arg_decls_t]),
'defn': sprintf(func_defn_tmpl,
[entry_name, arg_decls_v, n_args, arg_t, arg_v, ret_t, entry_name, entry_name])
});
}
return wrappers;
}
/*
=back
=cut
vim: expandtab shiftwidth=4 ft=javascript:
*/