# HG changeset patch # User Paul Boddie # Date 1480893455 -3600 # Node ID f1025f7d7d5e7023325b6a54d96e74f05a9ca067 # Parent 3ea74639e01f3b5501dd06cadb4c7fe3619f79b1 Omit the context when calling known plain functions or instantiators. diff -r 3ea74639e01f -r f1025f7d7d5e translator.py --- a/translator.py Sat Dec 03 17:47:21 2016 +0100 +++ b/translator.py Mon Dec 05 00:17:35 2016 +0100 @@ -990,6 +990,7 @@ target = None function = None literal_instantiation = False + context_required = True # Obtain details of the callable. @@ -999,6 +1000,7 @@ literal_instantiation = True parameters = None target = encode_literal_instantiator(objpath) + context_required = False # Identified targets employ function pointers directly. @@ -1010,6 +1012,7 @@ if expr.has_kind(""): target = encode_instantiator_pointer(objpath) target_structure = "&%s" % encode_bound_reference("%s.__init__" % objpath) + context_required = False # Only plain functions and bound methods employ function pointers. @@ -1018,24 +1021,35 @@ # Test for functions and methods. + method_class = self.is_method(objpath) accessor_kinds = expr.get_accessor_kinds() + instance_accessor = accessor_kinds and \ + len(accessor_kinds) == 1 and \ + first(accessor_kinds) == "" - if not self.is_method(objpath) or accessor_kinds and len(accessor_kinds) == 1 and first(accessor_kinds) == "": + if not method_class or instance_accessor: target = encode_function_pointer(objpath) target_structure = self.is_method(objpath) and \ encode_bound_reference(objpath) or \ "&%s" % encode_path(objpath) + if not method_class: + context_required = False + # Other targets are retrieved at run-time. else: parameters = None # Arguments are presented in a temporary frame array with any context - # always being the first argument (although it may be set to null for - # invocations where it would be unused). + # always being the first argument. Where it would be unused, it may be + # set to null. - args = ["__CONTEXT_AS_VALUE(__tmp_targets[%d])" % self.function_target] + if context_required: + args = ["__CONTEXT_AS_VALUE(__tmp_targets[%d])" % self.function_target] + else: + args = ["(__attr) {0, 0}"] + args += [None] * (not parameters and len(n.args) or parameters and len(parameters) or 0) kwcodes = [] kwargs = [] @@ -1068,6 +1082,9 @@ encode_symbol("ppos", arg.name), encode_symbol("pcode", arg.name))) + # Store non-keyword arguments in the argument list, rejecting + # superfluous arguments. + else: try: args[i+1] = str(argexpr) @@ -1118,7 +1135,8 @@ # Without a known specific callable, the expression provides the target. - stages.append("__tmp_targets[%d] = %s" % (self.function_target, expr)) + if not target or context_required: + stages.append("__tmp_targets[%d] = %s" % (self.function_target, expr)) # Any specific callable is then obtained.