# HG changeset patch # User Paul Boddie # Date 1488543911 -3600 # Node ID 7c8a7ad8dc500f262d4deadaaa09e41ec7db8585 # Parent 6843c1de351807e51a1efc4eacae25a8283c0681 Permit the parameterisation of the special instance indicator, making it match the position of the __class__ attribute, thus being different to any class type attribute position. diff -r 6843c1de3518 -r 7c8a7ad8dc50 generator.py --- a/generator.py Thu Mar 02 23:57:55 2017 +0100 +++ b/generator.py Fri Mar 03 13:25:11 2017 +0100 @@ -79,21 +79,27 @@ self.optimiser = optimiser self.output = output - def to_output(self, debug=False, gc_sections=False): + # The special instance indicator. + + self.instancepos = self.optimiser.attr_locations["__class__"] + + def to_output(self, reset=False, debug=False, gc_sections=False): "Write the generated code." self.check_output("debug=%r gc_sections=%r" % (debug, gc_sections)) self.write_structures() self.write_scripts(debug, gc_sections) - self.copy_templates() + self.copy_templates(reset) - def copy_templates(self): + def copy_templates(self, reset=False): "Copy template files to the generated output directory." templates = join(split(__file__)[0], "templates") + only_if_newer = not reset + for filename in listdir(templates): target = self.output pathname = join(templates, filename) @@ -101,7 +107,7 @@ # Copy files into the target directory. if not isdir(pathname): - copy(pathname, target) + copy(pathname, target, only_if_newer) # Copy directories (such as the native code directory). @@ -132,7 +138,7 @@ # Copy needed files. for filename in needed: - copy(join(pathname, filename), target) + copy(join(pathname, filename), target, only_if_newer) # Remove superfluous files. @@ -429,8 +435,8 @@ "Write scripts used to build the program." - f_native = open(join(self.output, "native.mk"), "w") - f_modules = open(join(self.output, "modules.mk"), "w") + # Options affect compiling and linking. + f_options = open(join(self.output, "options.mk"), "w") try: if debug: @@ -439,6 +445,15 @@ if gc_sections: print >>f_options, "include gc_sections.mk" + finally: + f_options.close() + + # Native and module definitions divide the program modules into native + # and generated code. + + f_native = open(join(self.output, "native.mk"), "w") + f_modules = open(join(self.output, "modules.mk"), "w") + try: # Identify modules used by the program. native_modules = [join("native", "common.c")] @@ -460,7 +475,22 @@ finally: f_native.close() f_modules.close() - f_options.close() + + # Instance position configuration uses the position of the ubiquitous + # __class__ attribute as a means of indicating that an object is an + # instance. Classes employ special identifying attributes that are + # positioned elsewhere and thus cannot be in the same location as the + # __class__ attribute. + + f_instancepos = open(join(self.output, "instancepos.h"), "w") + try: + print >>f_instancepos, """\ +#ifndef __INSTANCEPOS +#define __INSTANCEPOS %d +#endif +""" % self.instancepos + finally: + f_instancepos.close() def make_literal_constant(self, f_decls, f_defs, n, constant): @@ -738,7 +768,7 @@ print >>f_decls, "extern __obj %s;\n" % encode_path(structure_name) is_class = path and self.importer.get_object(path).has_kind("") - pos = is_class and encode_pos(encode_type_attribute(path)) or "0" + pos = is_class and encode_pos(encode_type_attribute(path)) or str(self.instancepos) print >>f_defs, """\ __obj %s = { diff -r 6843c1de3518 -r 7c8a7ad8dc50 templates/ops.c --- a/templates/ops.c Thu Mar 02 23:57:55 2017 +0100 +++ b/templates/ops.c Fri Mar 03 13:25:11 2017 +0100 @@ -17,6 +17,7 @@ */ #include "gc.h" /* GC_MALLOC, GC_REALLOC */ +#include "types.h" #include "ops.h" #include "progops.h" /* for raising errors */ #include "progconsts.h" diff -r 6843c1de3518 -r 7c8a7ad8dc50 templates/progops.c --- a/templates/progops.c Thu Mar 02 23:57:55 2017 +0100 +++ b/templates/progops.c Fri Mar 03 13:25:11 2017 +0100 @@ -31,6 +31,7 @@ { __ref obj = (__ref) __ALLOCATE(1, size); obj->table = table; + obj->pos = __INSTANCEPOS; __store_via_object(obj, __class__, (__attr) {.value=cls}); return (__attr) {.value=obj}; } diff -r 6843c1de3518 -r 7c8a7ad8dc50 templates/types.h --- a/templates/types.h Thu Mar 02 23:57:55 2017 +0100 +++ b/templates/types.h Fri Mar 03 13:25:11 2017 +0100 @@ -24,6 +24,13 @@ #include +/* Include the special instance position value. The pos member of __obj refers + to the special type attribute for classes, indicating which position holds + the attribute describing the class type. For instances, it is set to the same + attribute position as __class__ and is defined in the following file. */ + +#include "instancepos.h" + typedef uint16_t __code; typedef uint16_t __pos; typedef uint16_t __pcode; @@ -99,12 +106,6 @@ #define __FRAGMENT_SIZE(NUMBER) ((NUMBER) * sizeof(__attr) + 2 * sizeof(unsigned int)) -/* Special instance position value. The pos member of __obj refers to the - special type attribute for classes, indicating which position holds the - attribute describing the class type. For instances, it is set to zero. */ - -#define __INSTANCEPOS 0 - /* Attribute value setting. */ #define __ATTRVALUE(VALUE) ((__attr) {.value=VALUE})