1.1 --- a/encoders.py Tue Mar 21 18:45:42 2017 +0100
1.2 +++ b/encoders.py Thu Mar 23 16:40:57 2017 +0100
1.3 @@ -237,9 +237,13 @@
1.4 "<test_context_revert>", "<test_context_static>",
1.5 )
1.6
1.7 -reference_acting_ops = attribute_ops + checked_ops + typename_ops
1.8 +reference_acting_ops = attribute_ops + checked_ops + type_ops + typename_ops
1.9 attribute_producing_ops = attribute_loading_ops + checked_loading_ops
1.10
1.11 +attribute_producing_variables = (
1.12 + "<accessor>", "<context>", "<name>", "<private_context>", "<target_accessor>"
1.13 + )
1.14 +
1.15 def encode_access_instruction(instruction, subs, context_index):
1.16
1.17 """
1.18 @@ -340,13 +344,7 @@
1.19
1.20 if isinstance(arg, tuple):
1.21 encoded, substituted = encode_access_instruction(arg, subs, context_index)
1.22 -
1.23 - # Convert attribute results to references where required.
1.24 -
1.25 - if op and op in reference_acting_ops and arg[0] in attribute_producing_ops:
1.26 - return "%s.value" % encoded, substituted
1.27 - else:
1.28 - return encoded, substituted
1.29 + return attribute_to_reference(op, arg[0], encoded, substituted)
1.30
1.31 # Special values only need replacing, not encoding.
1.32
1.33 @@ -355,13 +353,18 @@
1.34 # Handle values modified by storage details.
1.35
1.36 if arg in context_values:
1.37 - return "%s(%s)" % (subs.get(arg), context_index), set([arg])
1.38 + encoded = "%s(%s)" % (subs.get(arg), context_index)
1.39 else:
1.40 - return subs.get(arg), set([arg])
1.41 + encoded = subs.get(arg)
1.42 +
1.43 + substituted = set([arg])
1.44 + return attribute_to_reference(op, arg, encoded, substituted)
1.45
1.46 # Convert static references to the appropriate type.
1.47
1.48 - elif op and op in reference_acting_ops and arg != "<accessor>":
1.49 + elif op and op in reference_acting_ops and \
1.50 + arg not in attribute_producing_variables:
1.51 +
1.52 return "&%s" % encode_path(arg), set()
1.53
1.54 # Other values may need encoding.
1.55 @@ -369,6 +372,18 @@
1.56 else:
1.57 return encode_path(arg), set()
1.58
1.59 +def attribute_to_reference(op, arg, encoded, substituted):
1.60 +
1.61 + # Convert attribute results to references where required.
1.62 +
1.63 + if op and op in reference_acting_ops and (
1.64 + arg in attribute_producing_ops or
1.65 + arg in attribute_producing_variables):
1.66 +
1.67 + return "__VALUE(%s)" % encoded, substituted
1.68 + else:
1.69 + return encoded, substituted
1.70 +
1.71 def encode_function_pointer(path):
1.72
1.73 "Encode 'path' as a reference to an output program function."