Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
435 lines (327 sloc) 11.2 KB
#! 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:
*/
Something went wrong with that request. Please try again.