1.1 --- a/optimiser.py Fri Mar 03 21:35:02 2017 +0100
1.2 +++ b/optimiser.py Sat Mar 04 00:20:25 2017 +0100
1.3 @@ -19,9 +19,8 @@
1.4 this program. If not, see <http://www.gnu.org/licenses/>.
1.5 """
1.6
1.7 -from common import add_counter_item, get_attrname_from_location, init_item, \
1.8 - sorted_output, CommonOutput
1.9 -from encoders import digest, encode_access_location, encode_instruction, get_kinds
1.10 +from common import init_item, sorted_output, CommonOutput
1.11 +from encoders import digest
1.12 from errors import OptimiseError
1.13 from os.path import exists, join
1.14 from os import makedirs
1.15 @@ -89,11 +88,6 @@
1.16 self.existing_paramnames = None
1.17 self.indicated_paramnames = None
1.18
1.19 - # Specific attribute access information.
1.20 -
1.21 - self.access_instructions = {}
1.22 - self.accessor_kinds = {}
1.23 -
1.24 # Object structure information.
1.25
1.26 self.structures = {}
1.27 @@ -124,7 +118,6 @@
1.28 self.position_parameters()
1.29 self.populate_tables()
1.30 self.populate_constants()
1.31 - self.initialise_access_instructions()
1.32
1.33 def need_reset(self):
1.34
1.35 @@ -266,23 +259,6 @@
1.36
1.37 ----
1.38
1.39 - Each attribute plan provides attribute details in the following format:
1.40 -
1.41 - location " " name " " test " " test type " " base
1.42 - " " traversed attributes " " traversed attribute ambiguity
1.43 - " " traversal access modes
1.44 - " " attributes to traverse " " attribute ambiguity
1.45 - " " context " " access method " " static attribute
1.46 -
1.47 - Locations have the following format:
1.48 -
1.49 - qualified name of scope "." local name ":" name version
1.50 -
1.51 - Traversal access modes are either "class" (obtain accessor class to
1.52 - access attribute) or "object" (obtain attribute directly from accessor).
1.53 -
1.54 - ----
1.55 -
1.56 The structures are presented as a table in the following format:
1.57
1.58 qualified name " " attribute names
1.59 @@ -356,20 +332,6 @@
1.60 finally:
1.61 f.close()
1.62
1.63 - f = open(join(self.output, "instruction_plans"), "w")
1.64 - try:
1.65 - access_instructions = self.access_instructions.items()
1.66 - access_instructions.sort()
1.67 -
1.68 - for location, instructions in access_instructions:
1.69 - print >>f, encode_access_location(location), "..."
1.70 - for instruction in instructions:
1.71 - print >>f, encode_instruction(instruction)
1.72 - print >>f
1.73 -
1.74 - finally:
1.75 - f.close()
1.76 -
1.77 f = open(join(self.output, "structures"), "w")
1.78 try:
1.79 structures = self.structures.items()
1.80 @@ -533,296 +495,6 @@
1.81 if not d.has_key(attrname):
1.82 d[attrname] = i
1.83
1.84 - def initialise_access_instructions(self):
1.85 -
1.86 - "Expand access plans into instruction sequences."
1.87 -
1.88 - for access_location, access_plan in self.deducer.access_plans.items():
1.89 -
1.90 - # Obtain the access details.
1.91 -
1.92 - name, test, test_type, base, \
1.93 - traversed, traversal_modes, attrnames, \
1.94 - context, context_test, \
1.95 - first_method, final_method, \
1.96 - origin, accessor_kinds = access_plan
1.97 -
1.98 - # Emit instructions by appending them to a list.
1.99 -
1.100 - instructions = []
1.101 - emit = instructions.append
1.102 -
1.103 - # Identify any static original accessor.
1.104 -
1.105 - if base:
1.106 - original_accessor = base
1.107 -
1.108 - # Employ names as contexts unless the context needs testing and
1.109 - # potentially updating. In such cases, temporary context storage is
1.110 - # used instead.
1.111 -
1.112 - elif name and not (context_test == "test" and
1.113 - final_method in ("access-invoke", "static-invoke")):
1.114 - original_accessor = "<name>" # refers to the name
1.115 -
1.116 - # Use a generic placeholder representing the access expression in
1.117 - # the general case.
1.118 -
1.119 - else:
1.120 - original_accessor = "<expr>"
1.121 -
1.122 - # Prepare for any first attribute access.
1.123 -
1.124 - if traversed:
1.125 - attrname = traversed[0]
1.126 - del traversed[0]
1.127 - elif attrnames:
1.128 - attrname = attrnames[0]
1.129 - del attrnames[0]
1.130 -
1.131 - # Perform the first access explicitly if at least one operation
1.132 - # requires it.
1.133 -
1.134 - access_first_attribute = final_method in ("access", "access-invoke", "assign") or traversed or attrnames
1.135 -
1.136 - # Determine whether the first access involves assignment.
1.137 -
1.138 - assigning = not traversed and not attrnames and final_method == "assign"
1.139 - set_accessor = assigning and "<set_target_accessor>" or "<set_accessor>"
1.140 - stored_accessor = assigning and "<target_accessor>" or "<accessor>"
1.141 -
1.142 - # Set the context if already available.
1.143 -
1.144 - context_var = None
1.145 -
1.146 - if context == "base":
1.147 - accessor = context_var = (base,)
1.148 - elif context == "original-accessor":
1.149 -
1.150 - # Prevent re-evaluation of any dynamic expression by storing it.
1.151 -
1.152 - if original_accessor == "<expr>":
1.153 - if final_method in ("access-invoke", "static-invoke"):
1.154 - emit(("<set_context>", original_accessor))
1.155 - accessor = context_var = ("<context>",)
1.156 - else:
1.157 - emit((set_accessor, original_accessor))
1.158 - accessor = context_var = (stored_accessor,)
1.159 - else:
1.160 - accessor = context_var = (original_accessor,)
1.161 -
1.162 - # Assigning does not set the context.
1.163 -
1.164 - elif context in ("final-accessor", "unset") and access_first_attribute:
1.165 -
1.166 - # Prevent re-evaluation of any dynamic expression by storing it.
1.167 -
1.168 - if original_accessor == "<expr>":
1.169 - emit((set_accessor, original_accessor))
1.170 - accessor = (stored_accessor,)
1.171 - else:
1.172 - accessor = (original_accessor,)
1.173 -
1.174 - # Apply any test.
1.175 -
1.176 - if test[0] == "test":
1.177 - accessor = ("__%s_%s_%s" % test, accessor, test_type)
1.178 -
1.179 - # Perform the first or final access.
1.180 - # The access only needs performing if the resulting accessor is used.
1.181 -
1.182 - remaining = len(traversed + attrnames)
1.183 -
1.184 - if access_first_attribute:
1.185 -
1.186 - if first_method == "relative-class":
1.187 - if assigning:
1.188 - emit(("__store_via_class", accessor, attrname, "<assexpr>"))
1.189 - else:
1.190 - accessor = ("__load_via_class", accessor, attrname)
1.191 -
1.192 - elif first_method == "relative-object":
1.193 - if assigning:
1.194 - emit(("__store_via_object", accessor, attrname, "<assexpr>"))
1.195 - else:
1.196 - accessor = ("__load_via_object", accessor, attrname)
1.197 -
1.198 - elif first_method == "relative-object-class":
1.199 - if assigning:
1.200 - emit(("__get_class_and_store", accessor, attrname, "<assexpr>"))
1.201 - else:
1.202 - accessor = ("__get_class_and_load", accessor, attrname)
1.203 -
1.204 - elif first_method == "check-class":
1.205 - if assigning:
1.206 - emit(("__check_and_store_via_class", accessor, attrname, "<assexpr>"))
1.207 - else:
1.208 - accessor = ("__check_and_load_via_class", accessor, attrname)
1.209 -
1.210 - elif first_method == "check-object":
1.211 - if assigning:
1.212 - emit(("__check_and_store_via_object", accessor, attrname, "<assexpr>"))
1.213 - else:
1.214 - accessor = ("__check_and_load_via_object", accessor, attrname)
1.215 -
1.216 - elif first_method == "check-object-class":
1.217 - if assigning:
1.218 - emit(("__check_and_store_via_any", accessor, attrname, "<assexpr>"))
1.219 - else:
1.220 - accessor = ("__check_and_load_via_any", accessor, attrname)
1.221 -
1.222 - # Traverse attributes using the accessor.
1.223 -
1.224 - if traversed:
1.225 - for attrname, traversal_mode in zip(traversed, traversal_modes):
1.226 - assigning = remaining == 1 and final_method == "assign"
1.227 -
1.228 - # Set the context, if appropriate.
1.229 -
1.230 - if remaining == 1 and final_method != "assign" and context == "final-accessor":
1.231 -
1.232 - # Invoked attributes employ a separate context accessed
1.233 - # during invocation.
1.234 -
1.235 - if final_method in ("access-invoke", "static-invoke"):
1.236 - emit(("<set_context>", accessor))
1.237 - accessor = context_var = "<context>"
1.238 -
1.239 - # A private context within the access is otherwise
1.240 - # retained.
1.241 -
1.242 - else:
1.243 - emit(("<set_private_context>", accessor))
1.244 - accessor = context_var = "<private_context>"
1.245 -
1.246 - # Perform the access only if not achieved directly.
1.247 -
1.248 - if remaining > 1 or final_method in ("access", "access-invoke", "assign"):
1.249 -
1.250 - if traversal_mode == "class":
1.251 - if assigning:
1.252 - emit(("__store_via_class", accessor, attrname, "<assexpr>"))
1.253 - else:
1.254 - accessor = ("__load_via_class", accessor, attrname)
1.255 - else:
1.256 - if assigning:
1.257 - emit(("__store_via_object", accessor, attrname, "<assexpr>"))
1.258 - else:
1.259 - accessor = ("__load_via_object", accessor, attrname)
1.260 -
1.261 - remaining -= 1
1.262 -
1.263 - if attrnames:
1.264 - for attrname in attrnames:
1.265 - assigning = remaining == 1 and final_method == "assign"
1.266 -
1.267 - # Set the context, if appropriate.
1.268 -
1.269 - if remaining == 1 and final_method != "assign" and context == "final-accessor":
1.270 -
1.271 - # Invoked attributes employ a separate context accessed
1.272 - # during invocation.
1.273 -
1.274 - if final_method in ("access-invoke", "static-invoke"):
1.275 - emit(("<set_context>", accessor))
1.276 - accessor = context_var = "<context>"
1.277 -
1.278 - # A private context within the access is otherwise
1.279 - # retained.
1.280 -
1.281 - else:
1.282 - emit(("<set_private_context>", accessor))
1.283 - accessor = context_var = "<private_context>"
1.284 -
1.285 - # Perform the access only if not achieved directly.
1.286 -
1.287 - if remaining > 1 or final_method in ("access", "access-invoke", "assign"):
1.288 -
1.289 - if assigning:
1.290 - emit(("__check_and_store_via_any", accessor, attrname, "<assexpr>"))
1.291 - else:
1.292 - accessor = ("__check_and_load_via_any", accessor, attrname)
1.293 -
1.294 - remaining -= 1
1.295 -
1.296 - # Define or emit the means of accessing the actual target.
1.297 -
1.298 - # Assignments to known attributes.
1.299 -
1.300 - if final_method == "static-assign":
1.301 - parent, attrname = origin.rsplit(".", 1)
1.302 - emit(("__store_via_object", parent, attrname, "<assexpr>"))
1.303 -
1.304 - # Invoked attributes employ a separate context.
1.305 -
1.306 - elif final_method in ("static", "static-invoke"):
1.307 - accessor = ("__load_static_ignore", origin)
1.308 -
1.309 - # Wrap accesses in context operations.
1.310 -
1.311 - if context_test == "test":
1.312 -
1.313 - # Test and combine the context with static attribute details.
1.314 -
1.315 - if final_method == "static":
1.316 - emit(("__load_static_test", context_var, origin))
1.317 -
1.318 - # Test the context, storing it separately if required for the
1.319 - # immediately invoked static attribute.
1.320 -
1.321 - elif final_method == "static-invoke":
1.322 - emit(("<test_context_static>", context_var, origin))
1.323 -
1.324 - # Test the context, storing it separately if required for an
1.325 - # immediately invoked attribute.
1.326 -
1.327 - elif final_method == "access-invoke":
1.328 - emit(("<test_context_revert>", context_var, accessor))
1.329 -
1.330 - # Test the context and update the attribute details if
1.331 - # appropriate.
1.332 -
1.333 - else:
1.334 - emit(("__test_context", context_var, accessor))
1.335 -
1.336 - elif context_test == "replace":
1.337 -
1.338 - # Produce an object with updated context.
1.339 -
1.340 - if final_method == "static":
1.341 - emit(("__load_static_replace", context_var, origin))
1.342 -
1.343 - # Omit the context update operation where the target is static
1.344 - # and the context is recorded separately.
1.345 -
1.346 - elif final_method == "static-invoke":
1.347 - pass
1.348 -
1.349 - # If a separate context is used for an immediate invocation,
1.350 - # produce the attribute details unchanged.
1.351 -
1.352 - elif final_method == "access-invoke":
1.353 - emit(accessor)
1.354 -
1.355 - # Update the context in the attribute details.
1.356 -
1.357 - else:
1.358 - emit(("__update_context", context_var, accessor))
1.359 -
1.360 - # Omit the accessor for assignments and for invocations of static
1.361 - # targets.
1.362 -
1.363 - elif final_method not in ("assign", "static-assign", "static-invoke"):
1.364 - emit(accessor)
1.365 -
1.366 - # Produce an advisory instruction regarding the context.
1.367 -
1.368 - if context_var:
1.369 - emit(("<context_identity>", context_var))
1.370 -
1.371 - self.access_instructions[access_location] = instructions
1.372 - self.accessor_kinds[access_location] = accessor_kinds
1.373 -
1.374 def get_ambiguity_for_attributes(self, attrnames):
1.375
1.376 """