1.1 --- a/generator.py Mon Mar 06 22:29:36 2017 +0100
1.2 +++ b/generator.py Tue Mar 07 00:28:18 2017 +0100
1.3 @@ -154,6 +154,8 @@
1.4 f_decls = open(join(self.output, "progtypes.h"), "w")
1.5 f_signatures = open(join(self.output, "main.h"), "w")
1.6 f_code = open(join(self.output, "main.c"), "w")
1.7 + f_calls = open(join(self.output, "calls.c"), "w")
1.8 + f_call_macros = open(join(self.output, "calls.h"), "w")
1.9
1.10 try:
1.11 # Output boilerplate.
1.12 @@ -193,6 +195,14 @@
1.13 #include "progtypes.h"
1.14 #include "main.h"
1.15 #include "progops.h"
1.16 +#include "calls.h"
1.17 +"""
1.18 +
1.19 + print >>f_call_macros, """\
1.20 +#ifndef __CALLS_H__
1.21 +#define __CALLS_H__
1.22 +
1.23 +#include "types.h"
1.24 """
1.25
1.26 # Generate table and structure data.
1.27 @@ -302,15 +312,18 @@
1.28 extra_function_instances.append(path)
1.29
1.30 # Write function declarations.
1.31 - # Signature: __attr <name>(__attr[]);
1.32 + # Signature: __attr <name>(...);
1.33
1.34 - print >>f_signatures, "__attr %s(__attr args[]);" % encode_function_pointer(path)
1.35 + parameters = self.importer.function_parameters[path]
1.36 + l = ["__attr"] * (len(parameters) + 1)
1.37 + print >>f_signatures, "__attr %s(%s);" % (encode_function_pointer(path), ", ".join(l))
1.38
1.39 # Generate parameter table size data.
1.40
1.41 min_parameters = {}
1.42 max_parameters = {}
1.43 size_parameters = {}
1.44 + all_max_parameters = set()
1.45
1.46 # Consolidate parameter tables for instantiators and functions.
1.47
1.48 @@ -339,6 +352,7 @@
1.49 min_parameters[signature] = argmin
1.50 max_parameters[signature] = argmax
1.51 size_parameters[signature] = len(parameters)
1.52 + all_max_parameters.add(argmax)
1.53
1.54 self.write_size_constants(f_consts, "pmin", min_parameters, 0)
1.55 self.write_size_constants(f_consts, "pmax", max_parameters, 0)
1.56 @@ -398,6 +412,42 @@
1.57 self.optimiser.locations,
1.58 "code", "pos", encode_code, encode_pos)
1.59
1.60 + # Generate macros for calls.
1.61 +
1.62 + all_max_parameters = list(all_max_parameters)
1.63 + all_max_parameters.sort()
1.64 +
1.65 + for argmax in all_max_parameters:
1.66 + l = []
1.67 + argnum = 0
1.68 + while argnum < argmax:
1.69 + l.append("ARGS[%d]" % argnum)
1.70 + argnum += 1
1.71 +
1.72 + print >>f_call_macros, "#define __CALL%d(FN, ARGS) (FN(%s))" % (argmax, ", ".join(l))
1.73 +
1.74 + # Generate a generic invocation function.
1.75 +
1.76 + print >>f_call_macros, "__attr __call_with_args(__attr (*fn)(), __attr args[], unsigned int n);"
1.77 +
1.78 + print >>f_calls, """\
1.79 +#include "types.h"
1.80 +#include "calls.h"
1.81 +
1.82 +__attr __call_with_args(__attr (*fn)(), __attr args[], unsigned int n)
1.83 +{
1.84 + switch (n)
1.85 + {"""
1.86 +
1.87 + for argmax in all_max_parameters:
1.88 + print >>f_calls, """\
1.89 + case %d: return __CALL%d(fn, args);""" % (argmax, argmax)
1.90 +
1.91 + print >>f_calls, """\
1.92 + default: return __NULL;
1.93 + }
1.94 +}"""
1.95 +
1.96 # Output more boilerplate.
1.97
1.98 print >>f_consts, """\
1.99 @@ -424,12 +474,18 @@
1.100
1.101 #endif /* __MAIN_H__ */"""
1.102
1.103 + print >>f_call_macros, """\
1.104 +
1.105 +#endif /* __CALLS_H__ */"""
1.106 +
1.107 finally:
1.108 f_consts.close()
1.109 f_defs.close()
1.110 f_decls.close()
1.111 f_signatures.close()
1.112 f_code.close()
1.113 + f_calls.close()
1.114 + f_call_macros.close()
1.115
1.116 def write_scripts(self, debug, gc_sections):
1.117
1.118 @@ -1126,6 +1182,8 @@
1.119 """
1.120
1.121 parameters = self.importer.function_parameters[init_ref.get_origin()]
1.122 + initialiser = init_ref.get_origin()
1.123 + argmin, argmax = self.get_argument_limits(initialiser)
1.124
1.125 print >>f_code, """\
1.126 __attr %s(__attr __args[])
1.127 @@ -1134,7 +1192,7 @@
1.128 __args[0] = __NEWINSTANCE(%s);
1.129
1.130 /* Call the initialiser. */
1.131 - %s(__args);
1.132 + %s(%s, __args);
1.133
1.134 /* Return the allocated object details. */
1.135 return __args[0];
1.136 @@ -1142,7 +1200,8 @@
1.137 """ % (
1.138 encode_instantiator_pointer(path),
1.139 encode_path(path),
1.140 - encode_function_pointer(init_ref.get_origin())
1.141 + "__CALL%d" % argmax,
1.142 + encode_function_pointer(initialiser)
1.143 )
1.144
1.145 print >>f_signatures, "#define __HAVE_%s" % encode_path(path)
1.146 @@ -1217,7 +1276,7 @@
1.147
1.148 fprintf(stderr, "Program terminated due to exception: %%s.\\n",
1.149 __load_via_object(
1.150 - %s(__ARGS(__NULL, __tmp_exc.arg)).value,
1.151 + %s(__NULL, __tmp_exc.arg).value,
1.152 __data__).strvalue);
1.153 return 1;
1.154 }