1.1 --- a/generator.py Thu Mar 23 16:40:57 2017 +0100
1.2 +++ b/generator.py Thu Mar 23 23:36:32 2017 +0100
1.3 @@ -43,6 +43,7 @@
1.4 # NOTE: These must be synchronised with the library.
1.5
1.6 function_type = "__builtins__.core.function"
1.7 + int_type = "__builtins__.int.int"
1.8 none_type = "__builtins__.none.NoneType"
1.9 string_type = "__builtins__.str.string"
1.10 type_type = "__builtins__.core.type"
1.11 @@ -359,6 +360,11 @@
1.12 for constant, n in self.optimiser.constants.items():
1.13 self.make_literal_constant(f_decls, f_defs, n, constant)
1.14
1.15 + # Generate a common integer instance object, referenced when integer
1.16 + # attributes are accessed.
1.17 +
1.18 + self.make_common_integer(f_decls, f_defs)
1.19 +
1.20 # Finish the main source file.
1.21
1.22 self.write_main_program(f_code, f_signatures)
1.23 @@ -504,6 +510,11 @@
1.24
1.25 value, value_type, encoding = constant
1.26
1.27 + # Do not generate individual integer constants.
1.28 +
1.29 + if value_type == self.int_type:
1.30 + return
1.31 +
1.32 const_path = encode_literal_constant(n)
1.33 structure_name = encode_literal_reference(n)
1.34
1.35 @@ -526,13 +537,23 @@
1.36
1.37 self.make_constant(f_decls, f_defs, ref, attr_path, structure_name)
1.38
1.39 + def make_common_integer(self, f_decls, f_defs):
1.40 +
1.41 + """
1.42 + Write common integer instance details to 'f_decls' (to declare a
1.43 + structure) and to 'f_defs' (to define the contents).
1.44 + """
1.45 +
1.46 + ref = Reference("<instance>", self.int_type)
1.47 + self.make_constant(f_decls, f_defs, ref, "__common_integer", "__common_integer_obj")
1.48 +
1.49 def make_constant(self, f_decls, f_defs, ref, const_path, structure_name, data=None, encoding=None):
1.50
1.51 """
1.52 Write constant details to 'f_decls' (to declare a structure) and to
1.53 'f_defs' (to define the contents) for the constant described by 'ref'
1.54 - having the given 'path' and 'structure_name' (for the constant structure
1.55 - itself).
1.56 + having the given 'const_path' (providing an attribute for the constant)
1.57 + and 'structure_name' (for the constant structure itself).
1.58
1.59 The additional 'data' and 'encoding' are used to describe specific
1.60 values.
1.61 @@ -974,7 +995,7 @@
1.62 # Special internal size member.
1.63
1.64 elif attrname == "__size__":
1.65 - structure.append("{.intvalue=%d}" % attr)
1.66 + structure.append("__INTVALUE(%d)" % attr)
1.67 continue
1.68
1.69 # Special internal key member.
1.70 @@ -1081,6 +1102,13 @@
1.71 # Obtain a constant value directly assigned to the attribute.
1.72
1.73 if self.optimiser.constant_numbers.has_key(alias):
1.74 +
1.75 + # Encode integer constants differently.
1.76 +
1.77 + value, value_type, encoding = self.importer.all_constant_values[alias]
1.78 + if value_type == self.int_type:
1.79 + return "__INTVALUE(%s) /* %s */" % (value, name)
1.80 +
1.81 constant_number = self.optimiser.constant_numbers[alias]
1.82 constant_value = encode_literal_constant(constant_number)
1.83 return "%s /* %s */" % (constant_value, name)
1.84 @@ -1213,13 +1241,11 @@
1.85 __Catch(__tmp_exc)
1.86 {
1.87 if (__ISINSTANCE(__tmp_exc.arg, __ATTRVALUE(&__builtins___exception_system_SystemExit)))
1.88 - return __load_via_object(
1.89 - __load_via_object(__tmp_exc.arg.value, __data__).value,
1.90 - value).intvalue;
1.91 + return __TOINT(__load_via_object(__VALUE(__tmp_exc.arg), value));
1.92
1.93 fprintf(stderr, "Program terminated due to exception: %%s.\\n",
1.94 __load_via_object(
1.95 - %s(__ARGS(__NULL, __tmp_exc.arg)).value,
1.96 + __VALUE(%s(__ARGS(__NULL, __tmp_exc.arg))),
1.97 __data__).strvalue);
1.98 return 1;
1.99 }