1.1 --- a/generator.py Sun Nov 14 00:50:17 2021 +0100
1.2 +++ b/generator.py Sun Nov 28 02:03:21 2021 +0100
1.3 @@ -192,6 +192,7 @@
1.4 print >>f_code, """\
1.5 #include <string.h>
1.6 #include <stdio.h>
1.7 +#include <threads.h>
1.8 #include "gc.h"
1.9 #include "signals.h"
1.10 #include "types.h"
1.11 @@ -277,8 +278,9 @@
1.12 # Write a table for all objects.
1.13
1.14 table = []
1.15 - self.populate_table(Reference(kind, path), table)
1.16 - self.write_table(f_decls, f_defs, table_name, structure_size, table)
1.17 + self.populate_table(ref, table)
1.18 + self.write_table(f_decls, f_defs, table_name, structure_size,
1.19 + table, ref)
1.20
1.21 # Generate function instances.
1.22
1.23 @@ -320,6 +322,9 @@
1.24 # Signature: __attr <name>(...);
1.25
1.26 parameters = self.importer.function_parameters[path]
1.27 +
1.28 + # Include the context plus the original parameters.
1.29 +
1.30 l = ["__attr"] * (len(parameters) + 1)
1.31 print >>f_signatures, "__attr %s(%s);" % (encode_function_pointer(path), ", ".join(l))
1.32
1.33 @@ -766,26 +771,41 @@
1.34 f_consts.write(" %s = %d" % (pos_encoder(attrname), i))
1.35 print >>f_consts, "\n };"
1.36
1.37 - def write_table(self, f_decls, f_defs, table_name, structure_size, table):
1.38 + def write_table(self, f_decls, f_defs, table_name, structure_size, table,
1.39 + ref):
1.40
1.41 """
1.42 Write the declarations to 'f_decls' and definitions to 'f_defs' for
1.43 the object having the given 'table_name' and the given 'structure_size',
1.44 with 'table' details used to populate the definition.
1.45 +
1.46 + To support value copying, the 'ref' is provided to be able to encode the
1.47 + structure size.
1.48 """
1.49
1.50 print >>f_decls, "extern const __table %s;\n" % table_name
1.51
1.52 + # Generate an object size of 0 for non-copyable types.
1.53 +
1.54 + path = ref.get_origin()
1.55 +
1.56 + if ref.get_kind() == "<instance>" and self.trailing_data_types.has_key(path):
1.57 + obj_type = encode_symbol("obj", path) or "__obj"
1.58 + obj_size = "sizeof(%s)" % obj_type
1.59 + else:
1.60 + obj_size = "0"
1.61 +
1.62 # Write the corresponding definition.
1.63
1.64 print >>f_defs, """\
1.65 const __table %s = {
1.66 %s,
1.67 + %s,
1.68 {
1.69 %s
1.70 }
1.71 };
1.72 -""" % (table_name, structure_size,
1.73 +""" % (table_name, structure_size, obj_size,
1.74 ",\n ".join(table))
1.75
1.76 def write_parameter_table(self, f_decls, f_defs, table_name, min_parameters,
1.77 @@ -1137,13 +1157,24 @@
1.78 the 'attrs' mapping, adding entries to the 'trailing' member collection.
1.79 """
1.80
1.81 + if self.get_trailing_data_type(ref):
1.82 + trailing.append(encode_literal_constant_value(attrs["__trailing__"]))
1.83 +
1.84 + def get_trailing_data_type(self, ref):
1.85 +
1.86 + """
1.87 + For the structure having the given 'ref', return the type of any
1.88 + trailing data.
1.89 + """
1.90 +
1.91 structure_ref = self.get_target_structure(ref)
1.92
1.93 # Instances with trailing data.
1.94
1.95 - if structure_ref.get_kind() == "<instance>" and \
1.96 - structure_ref.get_origin() in self.trailing_data_types:
1.97 - trailing.append(encode_literal_constant_value(attrs["__trailing__"]))
1.98 + if structure_ref.get_kind() == "<instance>":
1.99 + return self.trailing_data_types.get(structure_ref.get_origin())
1.100 + else:
1.101 + return None
1.102
1.103 def get_target_structure(self, ref):
1.104
1.105 @@ -1300,28 +1331,44 @@
1.106 """
1.107
1.108 print >>f_code, """\
1.109 +_Thread_local __attr __stack;
1.110 +
1.111 +/* Global used to prevent compiler over-optimisation. */
1.112 +
1.113 +__attr __stack_global;
1.114 +
1.115 int main(int argc, char *argv[])
1.116 {
1.117 __exc __tmp_exc;
1.118 + __attr __stack_base;
1.119
1.120 GC_INIT();
1.121
1.122 __signals_install_handlers();
1.123 + __stack = __stack_init();
1.124 +
1.125 + /* Record the stack accessor on the function stack for libgc. */
1.126 +
1.127 + __stack_base = __stack;
1.128 + __stack_global = __stack_base;
1.129
1.130 __Try
1.131 {"""
1.132
1.133 + # Write a main function invocation for all but the native modules.
1.134 +
1.135 for name in self.importer.order_modules():
1.136 + parts = name.split(".")
1.137 +
1.138 + if parts[0] == "native":
1.139 + continue
1.140 +
1.141 function_name = "__main_%s" % encode_path(name)
1.142 print >>f_signatures, "void %s();" % function_name
1.143 -
1.144 - # Omit the native modules.
1.145 + print >>f_code, """\
1.146 + %s();""" % function_name
1.147
1.148 - parts = name.split(".")
1.149 -
1.150 - if parts[0] != "native":
1.151 - print >>f_code, """\
1.152 - %s();""" % function_name
1.153 + # Finish the main section with an exception handler.
1.154
1.155 print >>f_code, """\
1.156 }