Lichen

Changeset

619:00ee53b9977b
2017-02-26 Paul Boddie raw files shortlog changelog graph Avoided using temporary target storage when names are used as accessors.
translator.py (file)
     1.1 --- a/translator.py	Sat Feb 25 22:19:53 2017 +0100
     1.2 +++ b/translator.py	Sun Feb 26 00:11:12 2017 +0100
     1.3 @@ -1310,18 +1310,26 @@
     1.4                          self.get_namespace_path(), n.lineno, num_parameters,
     1.5                          _objpath)
     1.6  
     1.7 +        # Determine any readily-accessible target identity.
     1.8 +
     1.9 +        target_identity = target or expr.is_name() and str(expr) or None
    1.10 +        target_var = target_identity or "__tmp_targets[%d]" % self.function_target
    1.11 +
    1.12 +        if not target_identity:
    1.13 +            self.record_temp("__tmp_targets")
    1.14 +
    1.15 +        if context_identity and context_identity.startswith("__tmp_contexts"):
    1.16 +            self.record_temp("__tmp_contexts")
    1.17 +
    1.18          # Arguments are presented in a temporary frame array with any context
    1.19          # always being the first argument. Where it would be unused, it may be
    1.20          # set to null.
    1.21  
    1.22          if context_required:
    1.23              if have_access_context:
    1.24 -                if context_identity.startswith("__tmp_contexts"):
    1.25 -                    self.record_temp("__tmp_contexts")
    1.26                  args = ["(__attr) {.value=%s}" % context_identity]
    1.27              else:
    1.28 -                self.record_temp("__tmp_targets")
    1.29 -                args = ["__CONTEXT_AS_VALUE(__tmp_targets[%d])" % self.function_target]
    1.30 +                args = ["__CONTEXT_AS_VALUE(%s)" % target_var]
    1.31          else:
    1.32              args = ["__NULL"]
    1.33  
    1.34 @@ -1421,9 +1429,8 @@
    1.35              if target:
    1.36                  if expr:
    1.37                      stages.append(str(expr))
    1.38 -            else:
    1.39 -                self.record_temp("__tmp_targets")
    1.40 -                stages.append("__tmp_targets[%d] = %s" % (self.function_target, expr))
    1.41 +            elif not target_identity:
    1.42 +                stages.append("%s = %s" % (target_var, expr))
    1.43  
    1.44          # Any specific callable is then obtained.
    1.45  
    1.46 @@ -1433,20 +1440,16 @@
    1.47          # Methods accessed via unidentified accessors are obtained. 
    1.48  
    1.49          elif function:
    1.50 -            self.record_temp("__tmp_targets")
    1.51 -
    1.52              if context_required:
    1.53                  if have_access_context:
    1.54 -                    if context_identity.startswith("__tmp_contexts"):
    1.55 -                        self.record_temp("__tmp_contexts")
    1.56 -                    stages.append("__get_function(%s, __tmp_targets[%d])" % (
    1.57 -                        context_identity, self.function_target))
    1.58 +                    stages.append("__get_function(%s, %s)" % (
    1.59 +                        context_identity, target_var))
    1.60                  else:
    1.61 -                    stages.append("__get_function(__CONTEXT_AS_VALUE(__tmp_targets[%d]).value, __tmp_targets[%d])" % (
    1.62 -                        self.function_target, self.function_target))
    1.63 +                    stages.append("__get_function(__CONTEXT_AS_VALUE(%s).value, %s)" % (
    1.64 +                        target_var, target_var))
    1.65              else:
    1.66 -                stages.append("__load_via_object(__tmp_targets[%d].value, %s).fn" % (
    1.67 -                    self.function_target, encode_symbol("pos", "__fn__")))
    1.68 +                stages.append("__load_via_object(%s.value, %s).fn" % (
    1.69 +                    target_var, encode_symbol("pos", "__fn__")))
    1.70  
    1.71          # With a known target, the function is obtained directly and called.
    1.72          # By putting the invocation at the end of the final element in the
    1.73 @@ -1465,9 +1468,8 @@
    1.74          # the callable and argument collections.
    1.75  
    1.76          else:
    1.77 -            self.record_temp("__tmp_targets")
    1.78 -            stages.append("__invoke(\n__tmp_targets[%d],\n%d, %d, %s, %s,\n%d, %s\n)" % (
    1.79 -                self.function_target,
    1.80 +            stages.append("__invoke(\n%s,\n%d, %d, %s, %s,\n%d, %s\n)" % (
    1.81 +                target_var,
    1.82                  self.always_callable and 1 or 0,
    1.83                  len(kwargs), kwcodestr, kwargstr,
    1.84                  len(args), argstr))