1.1 --- a/translator.py Sat Dec 03 17:47:21 2016 +0100
1.2 +++ b/translator.py Mon Dec 05 00:17:35 2016 +0100
1.3 @@ -990,6 +990,7 @@
1.4 target = None
1.5 function = None
1.6 literal_instantiation = False
1.7 + context_required = True
1.8
1.9 # Obtain details of the callable.
1.10
1.11 @@ -999,6 +1000,7 @@
1.12 literal_instantiation = True
1.13 parameters = None
1.14 target = encode_literal_instantiator(objpath)
1.15 + context_required = False
1.16
1.17 # Identified targets employ function pointers directly.
1.18
1.19 @@ -1010,6 +1012,7 @@
1.20 if expr.has_kind("<class>"):
1.21 target = encode_instantiator_pointer(objpath)
1.22 target_structure = "&%s" % encode_bound_reference("%s.__init__" % objpath)
1.23 + context_required = False
1.24
1.25 # Only plain functions and bound methods employ function pointers.
1.26
1.27 @@ -1018,24 +1021,35 @@
1.28
1.29 # Test for functions and methods.
1.30
1.31 + method_class = self.is_method(objpath)
1.32 accessor_kinds = expr.get_accessor_kinds()
1.33 + instance_accessor = accessor_kinds and \
1.34 + len(accessor_kinds) == 1 and \
1.35 + first(accessor_kinds) == "<instance>"
1.36
1.37 - if not self.is_method(objpath) or accessor_kinds and len(accessor_kinds) == 1 and first(accessor_kinds) == "<instance>":
1.38 + if not method_class or instance_accessor:
1.39 target = encode_function_pointer(objpath)
1.40 target_structure = self.is_method(objpath) and \
1.41 encode_bound_reference(objpath) or \
1.42 "&%s" % encode_path(objpath)
1.43
1.44 + if not method_class:
1.45 + context_required = False
1.46 +
1.47 # Other targets are retrieved at run-time.
1.48
1.49 else:
1.50 parameters = None
1.51
1.52 # Arguments are presented in a temporary frame array with any context
1.53 - # always being the first argument (although it may be set to null for
1.54 - # invocations where it would be unused).
1.55 + # always being the first argument. Where it would be unused, it may be
1.56 + # set to null.
1.57
1.58 - args = ["__CONTEXT_AS_VALUE(__tmp_targets[%d])" % self.function_target]
1.59 + if context_required:
1.60 + args = ["__CONTEXT_AS_VALUE(__tmp_targets[%d])" % self.function_target]
1.61 + else:
1.62 + args = ["(__attr) {0, 0}"]
1.63 +
1.64 args += [None] * (not parameters and len(n.args) or parameters and len(parameters) or 0)
1.65 kwcodes = []
1.66 kwargs = []
1.67 @@ -1068,6 +1082,9 @@
1.68 encode_symbol("ppos", arg.name),
1.69 encode_symbol("pcode", arg.name)))
1.70
1.71 + # Store non-keyword arguments in the argument list, rejecting
1.72 + # superfluous arguments.
1.73 +
1.74 else:
1.75 try:
1.76 args[i+1] = str(argexpr)
1.77 @@ -1118,7 +1135,8 @@
1.78
1.79 # Without a known specific callable, the expression provides the target.
1.80
1.81 - stages.append("__tmp_targets[%d] = %s" % (self.function_target, expr))
1.82 + if not target or context_required:
1.83 + stages.append("__tmp_targets[%d] = %s" % (self.function_target, expr))
1.84
1.85 # Any specific callable is then obtained.
1.86