1.1 --- a/generator.py Tue Nov 22 23:29:46 2016 +0100
1.2 +++ b/generator.py Tue Nov 22 23:31:03 2016 +0100
1.3 @@ -152,48 +152,6 @@
1.4 #include "main.h"
1.5 """
1.6
1.7 - # Generate structure size data.
1.8 -
1.9 - size_tables = {}
1.10 -
1.11 - for kind in ["<class>", "<module>", "<instance>"]:
1.12 - size_tables[kind] = {}
1.13 -
1.14 - for ref, structure in self.optimiser.structures.items():
1.15 - size_tables[ref.get_kind()][ref.get_origin()] = len(structure)
1.16 -
1.17 - size_tables = size_tables.items()
1.18 - size_tables.sort()
1.19 -
1.20 - for kind, sizes in size_tables:
1.21 - self.write_size_constants(f_consts, kind, sizes, 0)
1.22 -
1.23 - # Generate parameter table size data.
1.24 -
1.25 - min_sizes = {}
1.26 - max_sizes = {}
1.27 -
1.28 - for path, parameters in self.optimiser.parameters.items():
1.29 - argmin, argmax = self.get_argument_limits(path)
1.30 - min_sizes[path] = argmin
1.31 - max_sizes[path] = argmax
1.32 -
1.33 - # Record instantiator limits.
1.34 -
1.35 - if path.endswith(".__init__"):
1.36 - path = path[:-len(".__init__")]
1.37 -
1.38 - self.write_size_constants(f_consts, "pmin", min_sizes, 0)
1.39 - self.write_size_constants(f_consts, "pmax", max_sizes, 0)
1.40 -
1.41 - # Generate parameter codes.
1.42 -
1.43 - self.write_code_constants(f_consts, self.optimiser.all_paramnames, self.optimiser.arg_locations, "pcode", "ppos")
1.44 -
1.45 - # Generate attribute codes.
1.46 -
1.47 - self.write_code_constants(f_consts, self.optimiser.all_attrnames, self.optimiser.locations, "code", "pos")
1.48 -
1.49 # Generate table and structure data.
1.50
1.51 function_instance_attrs = None
1.52 @@ -238,7 +196,7 @@
1.53 if kind == "<class>":
1.54 self.write_instance_structure(f_decls, path, structure_size)
1.55
1.56 - self.write_structure(f_decls, f_defs, path, table_name, structure_size, structure,
1.57 + self.write_structure(f_decls, f_defs, path, table_name, structure,
1.58 kind == "<class>" and path)
1.59
1.60 # Record function instance details for function generation below.
1.61 @@ -258,6 +216,7 @@
1.62
1.63 functions = self.importer.function_parameters.keys()
1.64 functions.sort()
1.65 + extra_function_instances = []
1.66
1.67 for path in functions:
1.68
1.69 @@ -268,7 +227,7 @@
1.70
1.71 cls = self.function_type
1.72 table_name = encode_tablename("<instance>", cls)
1.73 - structure_size = encode_size("<instance>", cls)
1.74 + structure_size = encode_size("<instance>", path)
1.75
1.76 # Set a special callable attribute on the instance.
1.77
1.78 @@ -288,23 +247,24 @@
1.79 # A bound version of a method.
1.80
1.81 structure = self.populate_function(path, function_instance_attrs, False)
1.82 - self.write_structure(f_decls, f_defs, encode_bound_reference(path), table_name, structure_size, structure)
1.83 + self.write_structure(f_decls, f_defs, encode_bound_reference(path), table_name, structure)
1.84
1.85 # An unbound version of a method.
1.86
1.87 structure = self.populate_function(path, function_instance_attrs, True)
1.88 - self.write_structure(f_decls, f_defs, path, table_name, structure_size, structure)
1.89 + self.write_structure(f_decls, f_defs, path, table_name, structure)
1.90
1.91 else:
1.92 # A normal function.
1.93
1.94 structure = self.populate_function(path, function_instance_attrs, False)
1.95 - self.write_structure(f_decls, f_defs, path, table_name, structure_size, structure)
1.96 + self.write_structure(f_decls, f_defs, path, table_name, structure)
1.97
1.98 # Functions with defaults need to declare instance structures.
1.99
1.100 if self.importer.function_defaults.get(path):
1.101 self.write_instance_structure(f_decls, path, structure_size)
1.102 + extra_function_instances.append(path)
1.103
1.104 # Write function declarations.
1.105 # Signature: __attr <name>(__attr[]);
1.106 @@ -329,6 +289,55 @@
1.107
1.108 self.write_main_program(f_code, f_signatures)
1.109
1.110 + # Record size information for certain function instances as well as
1.111 + # for classes, modules and other instances.
1.112 +
1.113 + size_tables = {}
1.114 +
1.115 + for kind in ["<class>", "<module>", "<instance>"]:
1.116 + size_tables[kind] = {}
1.117 +
1.118 + # Generate structure size data.
1.119 +
1.120 + for ref, structure in self.optimiser.structures.items():
1.121 + size_tables[ref.get_kind()][ref.get_origin()] = len(structure)
1.122 +
1.123 + for path in extra_function_instances:
1.124 + defaults = self.importer.function_defaults[path]
1.125 + size_tables["<instance>"][path] = size_tables["<instance>"][self.function_type] + len(defaults)
1.126 +
1.127 + size_tables = size_tables.items()
1.128 + size_tables.sort()
1.129 +
1.130 + for kind, sizes in size_tables:
1.131 + self.write_size_constants(f_consts, kind, sizes, 0)
1.132 +
1.133 + # Generate parameter table size data.
1.134 +
1.135 + min_sizes = {}
1.136 + max_sizes = {}
1.137 +
1.138 + for path, parameters in self.optimiser.parameters.items():
1.139 + argmin, argmax = self.get_argument_limits(path)
1.140 + min_sizes[path] = argmin
1.141 + max_sizes[path] = argmax
1.142 +
1.143 + # Record instantiator limits.
1.144 +
1.145 + if path.endswith(".__init__"):
1.146 + path = path[:-len(".__init__")]
1.147 +
1.148 + self.write_size_constants(f_consts, "pmin", min_sizes, 0)
1.149 + self.write_size_constants(f_consts, "pmax", max_sizes, 0)
1.150 +
1.151 + # Generate parameter codes.
1.152 +
1.153 + self.write_code_constants(f_consts, self.optimiser.all_paramnames, self.optimiser.arg_locations, "pcode", "ppos")
1.154 +
1.155 + # Generate attribute codes.
1.156 +
1.157 + self.write_code_constants(f_consts, self.optimiser.all_attrnames, self.optimiser.locations, "code", "pos")
1.158 +
1.159 # Output more boilerplate.
1.160
1.161 print >>f_consts, """\
1.162 @@ -418,9 +427,8 @@
1.163
1.164 structure = []
1.165 table_name = encode_tablename("<instance>", cls)
1.166 - structure_size = encode_size("<instance>", cls)
1.167 self.populate_structure(ref, attrs, ref.get_kind(), structure)
1.168 - self.write_structure(f_decls, f_defs, structure_name, table_name, structure_size, structure)
1.169 + self.write_structure(f_decls, f_defs, structure_name, table_name, structure)
1.170
1.171 # Define a macro for the constant.
1.172
1.173 @@ -539,13 +547,12 @@
1.174 } %s;
1.175 """ % (structure_size, encode_symbol("obj", path))
1.176
1.177 - def write_structure(self, f_decls, f_defs, structure_name, table_name, structure_size, structure, path=None):
1.178 + def write_structure(self, f_decls, f_defs, structure_name, table_name, structure, path=None):
1.179
1.180 """
1.181 Write the declarations to 'f_decls' and definitions to 'f_defs' for
1.182 the object having the given 'structure_name', the given 'table_name',
1.183 - and the given 'structure_size', with 'structure' details used to
1.184 - populate the definition.
1.185 + and the given 'structure' details used to populate the definition.
1.186 """
1.187
1.188 if f_decls: