1.1 --- a/inspector.py Sat Nov 19 01:13:17 2016 +0100
1.2 +++ b/inspector.py Sat Nov 19 18:17:54 2016 +0100
1.3 @@ -1410,6 +1410,11 @@
1.4 requirements for the given 'path' and 'args'.
1.5 """
1.6
1.7 + # Class and module initialisation is ultimately combined.
1.8 +
1.9 + if not self.in_function:
1.10 + path = self.name
1.11 +
1.12 init_item(self.function_targets, path, lambda: [0, 0])
1.13 t = self.function_targets[path]
1.14 t[0] += 1
1.15 @@ -1424,6 +1429,11 @@
1.16
1.17 "Deallocate temporary argument storage for the given 'path' and 'args'."
1.18
1.19 + # Class and module initialisation is ultimately combined.
1.20 +
1.21 + if not self.in_function:
1.22 + path = self.name
1.23 +
1.24 self.function_targets[path][0] -= 1
1.25 self.function_arguments[path][0] -= len(args) + 1
1.26
2.1 --- a/translator.py Sat Nov 19 01:13:17 2016 +0100
2.2 +++ b/translator.py Sat Nov 19 18:17:54 2016 +0100
2.3 @@ -399,6 +399,7 @@
2.4 self.process_function_body_node(node)
2.5 else:
2.6 self.in_function = False
2.7 + self.function_target = 0
2.8 self.start_module()
2.9 self.process_structure(node)
2.10 self.end_module()
2.11 @@ -725,6 +726,7 @@
2.12
2.13 in_conditional = self.in_conditional
2.14 self.in_conditional = False
2.15 + self.function_target = 0
2.16
2.17 expr = self.process_structure_node(n.code) or PredefinedConstantRef("None")
2.18 if not isinstance(expr, ReturnRef):
2.19 @@ -874,11 +876,16 @@
2.20 # always being the first argument (although it may be set to null for
2.21 # invocations where it would be unused).
2.22
2.23 - args = ["__CONTEXT_AS_VALUE(__tmp_target)"]
2.24 + args = ["__CONTEXT_AS_VALUE(__tmp_targets[%d])" % self.function_target]
2.25 args += [None] * (not parameters and len(n.args) or parameters and len(parameters) or 0)
2.26 kwcodes = []
2.27 kwargs = []
2.28
2.29 + # Any invocations in the arguments will store target details in a
2.30 + # different location.
2.31 +
2.32 + self.function_target += 1
2.33 +
2.34 for i, arg in enumerate(n.args):
2.35 argexpr = self.process_structure_node(arg)
2.36
2.37 @@ -905,6 +912,10 @@
2.38 else:
2.39 args[i+1] = str(argexpr)
2.40
2.41 + # Reference the current target again.
2.42 +
2.43 + self.function_target -= 1
2.44 +
2.45 # Defaults are added to the frame where arguments are missing.
2.46
2.47 if parameters:
2.48 @@ -944,7 +955,7 @@
2.49
2.50 # Without a known specific callable, the expression provides the target.
2.51
2.52 - stages.append("__tmp_target = %s" % expr)
2.53 + stages.append("__tmp_targets[%d] = %s" % (self.function_target, expr))
2.54
2.55 # Any specific callable is then obtained.
2.56
2.57 @@ -960,8 +971,9 @@
2.58 # the callable and argument collections.
2.59
2.60 else:
2.61 - output = "(%s, __invoke(\n__tmp_target,\n%d, %d, %s, %s,\n%d, %s\n))" % (
2.62 + output = "(%s, __invoke(\n__tmp_targets[%d],\n%d, %d, %s, %s,\n%d, %s\n))" % (
2.63 ",\n".join(stages),
2.64 + self.function_target,
2.65 self.always_callable and 1 or 0,
2.66 len(kwargs), kwcodestr, kwargstr,
2.67 len(args), argstr)
2.68 @@ -1322,7 +1334,7 @@
2.69 print >>self.out, "void __main_%s()" % encode_path(self.name)
2.70 print >>self.out, "{"
2.71 self.indent += 1
2.72 - self.write_temporaries()
2.73 + self.write_temporaries(self.importer.function_targets.get(self.name))
2.74
2.75 def end_module(self):
2.76
2.77 @@ -1338,7 +1350,7 @@
2.78 print >>self.out, "__attr %s(__attr __args[])" % encode_function_pointer(name)
2.79 print >>self.out, "{"
2.80 self.indent += 1
2.81 - self.write_temporaries()
2.82 + self.write_temporaries(self.importer.function_targets.get(name))
2.83
2.84 # Obtain local names from parameters.
2.85
2.86 @@ -1373,12 +1385,17 @@
2.87 print >>self.out, "}"
2.88 print >>self.out
2.89
2.90 - def write_temporaries(self):
2.91 + def write_temporaries(self, targets):
2.92
2.93 - "Write temporary storage employed by functions."
2.94 + """
2.95 + Write temporary storage employed by functions, providing space for the
2.96 + given number of 'targets'.
2.97 + """
2.98 +
2.99 + targets = targets is not None and "__tmp_targets[%d], " % targets or ""
2.100
2.101 self.writeline("__ref __tmp_context, __tmp_value;")
2.102 - self.writeline("__attr __tmp_target, __tmp_result;")
2.103 + self.writeline("__attr %s__tmp_result;" % targets)
2.104 self.writeline("__exc __tmp_exc;")
2.105
2.106 def write_parameters(self, name, define=True):