1.1 --- a/optimiser.py Sat Feb 18 20:20:06 2017 +0100
1.2 +++ b/optimiser.py Sun Feb 19 00:48:28 2017 +0100
1.3 @@ -351,9 +351,13 @@
1.4 first_method, final_method, \
1.5 origin, accessor_kinds = access_plan
1.6
1.7 + # Emit instructions by appending them to a list.
1.8 +
1.9 instructions = []
1.10 emit = instructions.append
1.11
1.12 + # Identify any static original accessor.
1.13 +
1.14 if base:
1.15 original_accessor = base
1.16 else:
1.17 @@ -466,9 +470,17 @@
1.18 # Set the context, if appropriate.
1.19
1.20 if remaining == 1 and final_method != "assign" and context == "final-accessor":
1.21 +
1.22 + # Invoked attributes employ a separate context accessed
1.23 + # during invocation.
1.24 +
1.25 if final_method in ("access-invoke", "static-invoke"):
1.26 emit(("<set_context>", accessor))
1.27 accessor = context_var = "<context>"
1.28 +
1.29 + # A private context within the access is otherwise
1.30 + # retained.
1.31 +
1.32 else:
1.33 emit(("<set_private_context>", accessor))
1.34 accessor = context_var = "<private_context>"
1.35 @@ -497,9 +509,17 @@
1.36 # Set the context, if appropriate.
1.37
1.38 if remaining == 1 and final_method != "assign" and context == "final-accessor":
1.39 +
1.40 + # Invoked attributes employ a separate context accessed
1.41 + # during invocation.
1.42 +
1.43 if final_method in ("access-invoke", "static-invoke"):
1.44 emit(("<set_context>", accessor))
1.45 accessor = context_var = "<context>"
1.46 +
1.47 + # A private context within the access is otherwise
1.48 + # retained.
1.49 +
1.50 else:
1.51 emit(("<set_private_context>", accessor))
1.52 accessor = context_var = "<private_context>"
1.53 @@ -531,12 +551,27 @@
1.54 # Wrap accesses in context operations.
1.55
1.56 if context_test == "test":
1.57 +
1.58 + # Test and combine the context with static attribute details.
1.59 +
1.60 if final_method == "static":
1.61 emit(("__load_static_test", context_var, origin))
1.62 +
1.63 + # Test the context, storing it separately if required for the
1.64 + # immediately invoked static attribute.
1.65 +
1.66 elif final_method == "static-invoke":
1.67 emit(("<test_context_static>", context_var, origin))
1.68 +
1.69 + # Test the context, storing it separately if required for an
1.70 + # immediately invoked attribute.
1.71 +
1.72 elif final_method == "access-invoke":
1.73 emit(("<test_context>", context_var, accessor))
1.74 +
1.75 + # Test the context and update the attribute details if
1.76 + # appropriate.
1.77 +
1.78 else:
1.79 emit(("__test_context", context_var, accessor))
1.80
1.81 @@ -553,13 +588,16 @@
1.82 elif final_method == "static-invoke":
1.83 pass
1.84
1.85 - # Only update any context if no separate context is used.
1.86 + # If a separate context is used for an immediate invocation,
1.87 + # produce the attribute details unchanged.
1.88
1.89 - elif final_method != "access-invoke":
1.90 - emit(("__update_context", context_var, accessor))
1.91 + elif final_method == "access-invoke":
1.92 + emit(accessor)
1.93 +
1.94 + # Update the context in the attribute details.
1.95
1.96 else:
1.97 - emit(accessor)
1.98 + emit(("__update_context", context_var, accessor))
1.99
1.100 # Omit the accessor for assignments and for invocations of static
1.101 # targets.