1.1 --- a/encoders.py Fri Feb 17 18:49:57 2017 +0100
1.2 +++ b/encoders.py Fri Feb 17 18:52:18 2017 +0100
1.3 @@ -210,10 +210,18 @@
1.4 "__load_static_ignore", "__load_static_replace", "__load_static_test",
1.5 )
1.6
1.7 +context_values = (
1.8 + "<context>",
1.9 + )
1.10 +
1.11 +context_ops = (
1.12 + "<context>", "<set_context>",
1.13 + )
1.14 +
1.15 reference_acting_ops = attribute_ops + checked_ops + typename_ops
1.16 attribute_producing_ops = attribute_loading_ops + checked_loading_ops
1.17
1.18 -def encode_access_instruction(instruction, subs):
1.19 +def encode_access_instruction(instruction, subs, context_index):
1.20
1.21 """
1.22 Encode the 'instruction' - a sequence starting with an operation and
1.23 @@ -223,6 +231,9 @@
1.24 The 'subs' parameter defines a mapping of substitutions for special values
1.25 used in instructions.
1.26
1.27 + The 'context_index' parameter defines the position in local context storage
1.28 + for the referenced context or affected by a context operation.
1.29 +
1.30 Return both the encoded instruction and a collection of substituted names.
1.31 """
1.32
1.33 @@ -230,53 +241,60 @@
1.34 args = instruction[1:]
1.35 substituted = set()
1.36
1.37 - if not args:
1.38 - argstr = ""
1.39 + # Encode the arguments.
1.40
1.41 - else:
1.42 - # Encode the arguments.
1.43 -
1.44 - a = []
1.45 + a = []
1.46 + if args:
1.47 converting_op = op
1.48 for arg in args:
1.49 - s, _substituted = encode_access_instruction_arg(arg, subs, converting_op)
1.50 + s, _substituted = encode_access_instruction_arg(arg, subs, converting_op, context_index)
1.51 substituted.update(_substituted)
1.52 a.append(s)
1.53 converting_op = None
1.54
1.55 - # Modify certain arguments.
1.56 + # Modify certain arguments.
1.57
1.58 - # Convert attribute name arguments to position symbols.
1.59 + # Convert attribute name arguments to position symbols.
1.60
1.61 - if op in attribute_ops:
1.62 - arg = a[1]
1.63 - a[1] = encode_symbol("pos", arg)
1.64 + if op in attribute_ops:
1.65 + arg = a[1]
1.66 + a[1] = encode_symbol("pos", arg)
1.67 +
1.68 + # Convert attribute name arguments to position and code symbols.
1.69
1.70 - # Convert attribute name arguments to position and code symbols.
1.71 + elif op in checked_ops:
1.72 + arg = a[1]
1.73 + a[1] = encode_symbol("pos", arg)
1.74 + a.insert(2, encode_symbol("code", arg))
1.75
1.76 - elif op in checked_ops:
1.77 - arg = a[1]
1.78 - a[1] = encode_symbol("pos", arg)
1.79 - a.insert(2, encode_symbol("code", arg))
1.80 + # Convert type name arguments to position and code symbols.
1.81
1.82 - # Convert type name arguments to position and code symbols.
1.83 + elif op in typename_ops:
1.84 + arg = encode_type_attribute(args[1])
1.85 + a[1] = encode_symbol("pos", arg)
1.86 + a.insert(2, encode_symbol("code", arg))
1.87
1.88 - elif op in typename_ops:
1.89 - arg = encode_type_attribute(args[1])
1.90 - a[1] = encode_symbol("pos", arg)
1.91 - a.insert(2, encode_symbol("code", arg))
1.92 + # Obtain addresses of type arguments.
1.93 +
1.94 + elif op in type_ops:
1.95 + a[1] = "&%s" % a[1]
1.96
1.97 - # Obtain addresses of type arguments.
1.98 + # Obtain addresses of static objects.
1.99 +
1.100 + elif op in static_ops:
1.101 + a[-1] = "&%s" % a[-1]
1.102
1.103 - elif op in type_ops:
1.104 - a[1] = "&%s" % a[1]
1.105 + # Add context storage information to certain operations.
1.106
1.107 - # Obtain addresses of static objects.
1.108 + elif op in context_ops:
1.109 + a.insert(0, context_index)
1.110
1.111 - elif op in static_ops:
1.112 - a[-1] = "&%s" % a[-1]
1.113 + # Define any argument string.
1.114
1.115 + if a:
1.116 argstr = "(%s)" % ", ".join(map(str, a))
1.117 + else:
1.118 + argstr = ""
1.119
1.120 # Substitute the first element of the instruction, which may not be an
1.121 # operation at all.
1.122 @@ -300,16 +318,19 @@
1.123
1.124 return "%s%s" % (op, argstr), substituted
1.125
1.126 -def encode_access_instruction_arg(arg, subs, op):
1.127 +def encode_access_instruction_arg(arg, subs, op, context_index):
1.128
1.129 """
1.130 - Encode 'arg' using 'subs' to define substitutions, returning a tuple
1.131 - containing the encoded form of 'arg' along with a collection of any
1.132 - substituted values.
1.133 + Encode 'arg' using 'subs' to define substitutions, 'op' to indicate the
1.134 + operation to which the argument belongs, and 'context_index' to indicate any
1.135 + affected context storage.
1.136 +
1.137 + Return a tuple containing the encoded form of 'arg' along with a collection
1.138 + of any substituted values.
1.139 """
1.140
1.141 if isinstance(arg, tuple):
1.142 - encoded, substituted = encode_access_instruction(arg, subs)
1.143 + encoded, substituted = encode_access_instruction(arg, subs, context_index)
1.144
1.145 # Convert attribute results to references where required.
1.146
1.147 @@ -321,7 +342,13 @@
1.148 # Special values only need replacing, not encoding.
1.149
1.150 elif subs.has_key(arg):
1.151 - return subs.get(arg), set([arg])
1.152 +
1.153 + # Handle values modified by storage details.
1.154 +
1.155 + if arg in context_values:
1.156 + return "%s(%s)" % (subs.get(arg), context_index), set([arg])
1.157 + else:
1.158 + return subs.get(arg), set([arg])
1.159
1.160 # Convert static references to the appropriate type.
1.161