1.1 --- a/generator.py Thu Mar 02 23:57:55 2017 +0100
1.2 +++ b/generator.py Fri Mar 03 13:25:11 2017 +0100
1.3 @@ -79,21 +79,27 @@
1.4 self.optimiser = optimiser
1.5 self.output = output
1.6
1.7 - def to_output(self, debug=False, gc_sections=False):
1.8 + # The special instance indicator.
1.9 +
1.10 + self.instancepos = self.optimiser.attr_locations["__class__"]
1.11 +
1.12 + def to_output(self, reset=False, debug=False, gc_sections=False):
1.13
1.14 "Write the generated code."
1.15
1.16 self.check_output("debug=%r gc_sections=%r" % (debug, gc_sections))
1.17 self.write_structures()
1.18 self.write_scripts(debug, gc_sections)
1.19 - self.copy_templates()
1.20 + self.copy_templates(reset)
1.21
1.22 - def copy_templates(self):
1.23 + def copy_templates(self, reset=False):
1.24
1.25 "Copy template files to the generated output directory."
1.26
1.27 templates = join(split(__file__)[0], "templates")
1.28
1.29 + only_if_newer = not reset
1.30 +
1.31 for filename in listdir(templates):
1.32 target = self.output
1.33 pathname = join(templates, filename)
1.34 @@ -101,7 +107,7 @@
1.35 # Copy files into the target directory.
1.36
1.37 if not isdir(pathname):
1.38 - copy(pathname, target)
1.39 + copy(pathname, target, only_if_newer)
1.40
1.41 # Copy directories (such as the native code directory).
1.42
1.43 @@ -132,7 +138,7 @@
1.44 # Copy needed files.
1.45
1.46 for filename in needed:
1.47 - copy(join(pathname, filename), target)
1.48 + copy(join(pathname, filename), target, only_if_newer)
1.49
1.50 # Remove superfluous files.
1.51
1.52 @@ -429,8 +435,8 @@
1.53
1.54 "Write scripts used to build the program."
1.55
1.56 - f_native = open(join(self.output, "native.mk"), "w")
1.57 - f_modules = open(join(self.output, "modules.mk"), "w")
1.58 + # Options affect compiling and linking.
1.59 +
1.60 f_options = open(join(self.output, "options.mk"), "w")
1.61 try:
1.62 if debug:
1.63 @@ -439,6 +445,15 @@
1.64 if gc_sections:
1.65 print >>f_options, "include gc_sections.mk"
1.66
1.67 + finally:
1.68 + f_options.close()
1.69 +
1.70 + # Native and module definitions divide the program modules into native
1.71 + # and generated code.
1.72 +
1.73 + f_native = open(join(self.output, "native.mk"), "w")
1.74 + f_modules = open(join(self.output, "modules.mk"), "w")
1.75 + try:
1.76 # Identify modules used by the program.
1.77
1.78 native_modules = [join("native", "common.c")]
1.79 @@ -460,7 +475,22 @@
1.80 finally:
1.81 f_native.close()
1.82 f_modules.close()
1.83 - f_options.close()
1.84 +
1.85 + # Instance position configuration uses the position of the ubiquitous
1.86 + # __class__ attribute as a means of indicating that an object is an
1.87 + # instance. Classes employ special identifying attributes that are
1.88 + # positioned elsewhere and thus cannot be in the same location as the
1.89 + # __class__ attribute.
1.90 +
1.91 + f_instancepos = open(join(self.output, "instancepos.h"), "w")
1.92 + try:
1.93 + print >>f_instancepos, """\
1.94 +#ifndef __INSTANCEPOS
1.95 +#define __INSTANCEPOS %d
1.96 +#endif
1.97 +""" % self.instancepos
1.98 + finally:
1.99 + f_instancepos.close()
1.100
1.101 def make_literal_constant(self, f_decls, f_defs, n, constant):
1.102
1.103 @@ -738,7 +768,7 @@
1.104 print >>f_decls, "extern __obj %s;\n" % encode_path(structure_name)
1.105
1.106 is_class = path and self.importer.get_object(path).has_kind("<class>")
1.107 - pos = is_class and encode_pos(encode_type_attribute(path)) or "0"
1.108 + pos = is_class and encode_pos(encode_type_attribute(path)) or str(self.instancepos)
1.109
1.110 print >>f_defs, """\
1.111 __obj %s = {
2.1 --- a/templates/ops.c Thu Mar 02 23:57:55 2017 +0100
2.2 +++ b/templates/ops.c Fri Mar 03 13:25:11 2017 +0100
2.3 @@ -17,6 +17,7 @@
2.4 */
2.5
2.6 #include "gc.h" /* GC_MALLOC, GC_REALLOC */
2.7 +#include "types.h"
2.8 #include "ops.h"
2.9 #include "progops.h" /* for raising errors */
2.10 #include "progconsts.h"
3.1 --- a/templates/progops.c Thu Mar 02 23:57:55 2017 +0100
3.2 +++ b/templates/progops.c Fri Mar 03 13:25:11 2017 +0100
3.3 @@ -31,6 +31,7 @@
3.4 {
3.5 __ref obj = (__ref) __ALLOCATE(1, size);
3.6 obj->table = table;
3.7 + obj->pos = __INSTANCEPOS;
3.8 __store_via_object(obj, __class__, (__attr) {.value=cls});
3.9 return (__attr) {.value=obj};
3.10 }
4.1 --- a/templates/types.h Thu Mar 02 23:57:55 2017 +0100
4.2 +++ b/templates/types.h Fri Mar 03 13:25:11 2017 +0100
4.3 @@ -24,6 +24,13 @@
4.4
4.5 #include <stdint.h>
4.6
4.7 +/* Include the special instance position value. The pos member of __obj refers
4.8 + to the special type attribute for classes, indicating which position holds
4.9 + the attribute describing the class type. For instances, it is set to the same
4.10 + attribute position as __class__ and is defined in the following file. */
4.11 +
4.12 +#include "instancepos.h"
4.13 +
4.14 typedef uint16_t __code;
4.15 typedef uint16_t __pos;
4.16 typedef uint16_t __pcode;
4.17 @@ -99,12 +106,6 @@
4.18
4.19 #define __FRAGMENT_SIZE(NUMBER) ((NUMBER) * sizeof(__attr) + 2 * sizeof(unsigned int))
4.20
4.21 -/* Special instance position value. The pos member of __obj refers to the
4.22 - special type attribute for classes, indicating which position holds the
4.23 - attribute describing the class type. For instances, it is set to zero. */
4.24 -
4.25 -#define __INSTANCEPOS 0
4.26 -
4.27 /* Attribute value setting. */
4.28
4.29 #define __ATTRVALUE(VALUE) ((__attr) {.value=VALUE})