1.1 --- a/translator.py Sat Nov 19 01:13:17 2016 +0100
1.2 +++ b/translator.py Sat Nov 19 18:17:54 2016 +0100
1.3 @@ -399,6 +399,7 @@
1.4 self.process_function_body_node(node)
1.5 else:
1.6 self.in_function = False
1.7 + self.function_target = 0
1.8 self.start_module()
1.9 self.process_structure(node)
1.10 self.end_module()
1.11 @@ -725,6 +726,7 @@
1.12
1.13 in_conditional = self.in_conditional
1.14 self.in_conditional = False
1.15 + self.function_target = 0
1.16
1.17 expr = self.process_structure_node(n.code) or PredefinedConstantRef("None")
1.18 if not isinstance(expr, ReturnRef):
1.19 @@ -874,11 +876,16 @@
1.20 # always being the first argument (although it may be set to null for
1.21 # invocations where it would be unused).
1.22
1.23 - args = ["__CONTEXT_AS_VALUE(__tmp_target)"]
1.24 + args = ["__CONTEXT_AS_VALUE(__tmp_targets[%d])" % self.function_target]
1.25 args += [None] * (not parameters and len(n.args) or parameters and len(parameters) or 0)
1.26 kwcodes = []
1.27 kwargs = []
1.28
1.29 + # Any invocations in the arguments will store target details in a
1.30 + # different location.
1.31 +
1.32 + self.function_target += 1
1.33 +
1.34 for i, arg in enumerate(n.args):
1.35 argexpr = self.process_structure_node(arg)
1.36
1.37 @@ -905,6 +912,10 @@
1.38 else:
1.39 args[i+1] = str(argexpr)
1.40
1.41 + # Reference the current target again.
1.42 +
1.43 + self.function_target -= 1
1.44 +
1.45 # Defaults are added to the frame where arguments are missing.
1.46
1.47 if parameters:
1.48 @@ -944,7 +955,7 @@
1.49
1.50 # Without a known specific callable, the expression provides the target.
1.51
1.52 - stages.append("__tmp_target = %s" % expr)
1.53 + stages.append("__tmp_targets[%d] = %s" % (self.function_target, expr))
1.54
1.55 # Any specific callable is then obtained.
1.56
1.57 @@ -960,8 +971,9 @@
1.58 # the callable and argument collections.
1.59
1.60 else:
1.61 - output = "(%s, __invoke(\n__tmp_target,\n%d, %d, %s, %s,\n%d, %s\n))" % (
1.62 + output = "(%s, __invoke(\n__tmp_targets[%d],\n%d, %d, %s, %s,\n%d, %s\n))" % (
1.63 ",\n".join(stages),
1.64 + self.function_target,
1.65 self.always_callable and 1 or 0,
1.66 len(kwargs), kwcodestr, kwargstr,
1.67 len(args), argstr)
1.68 @@ -1322,7 +1334,7 @@
1.69 print >>self.out, "void __main_%s()" % encode_path(self.name)
1.70 print >>self.out, "{"
1.71 self.indent += 1
1.72 - self.write_temporaries()
1.73 + self.write_temporaries(self.importer.function_targets.get(self.name))
1.74
1.75 def end_module(self):
1.76
1.77 @@ -1338,7 +1350,7 @@
1.78 print >>self.out, "__attr %s(__attr __args[])" % encode_function_pointer(name)
1.79 print >>self.out, "{"
1.80 self.indent += 1
1.81 - self.write_temporaries()
1.82 + self.write_temporaries(self.importer.function_targets.get(name))
1.83
1.84 # Obtain local names from parameters.
1.85
1.86 @@ -1373,12 +1385,17 @@
1.87 print >>self.out, "}"
1.88 print >>self.out
1.89
1.90 - def write_temporaries(self):
1.91 + def write_temporaries(self, targets):
1.92
1.93 - "Write temporary storage employed by functions."
1.94 + """
1.95 + Write temporary storage employed by functions, providing space for the
1.96 + given number of 'targets'.
1.97 + """
1.98 +
1.99 + targets = targets is not None and "__tmp_targets[%d], " % targets or ""
1.100
1.101 self.writeline("__ref __tmp_context, __tmp_value;")
1.102 - self.writeline("__attr __tmp_target, __tmp_result;")
1.103 + self.writeline("__attr %s__tmp_result;" % targets)
1.104 self.writeline("__exc __tmp_exc;")
1.105
1.106 def write_parameters(self, name, define=True):