# HG changeset patch # User Paul Boddie # Date 1487445227 -3600 # Node ID 767f7ac69ef2d2e6e69f045dc2866f90a88695d6 # Parent 3e5b14c95a551054e7298186c5257c465b2268fb Introduced a context test that sets a local context where an attribute is invoked immediately. diff -r 3e5b14c95a55 -r 767f7ac69ef2 encoders.py --- a/encoders.py Sat Feb 18 18:52:04 2017 +0100 +++ b/encoders.py Sat Feb 18 20:13:47 2017 +0100 @@ -215,7 +215,7 @@ ) context_ops = ( - "", "", + "", "", "", ) reference_acting_ops = attribute_ops + checked_ops + typename_ops diff -r 3e5b14c95a55 -r 767f7ac69ef2 optimiser.py --- a/optimiser.py Sat Feb 18 18:52:04 2017 +0100 +++ b/optimiser.py Sat Feb 18 20:13:47 2017 +0100 @@ -533,6 +533,8 @@ if context_test == "test": if final_method in ("static", "static-invoke"): emit(("__load_static_test", context_var, origin)) + elif final_method == "access-invoke": + emit(("", context_var, accessor)) else: emit(("__test_context", context_var, accessor)) diff -r 3e5b14c95a55 -r 767f7ac69ef2 templates/ops.c --- a/templates/ops.c Sat Feb 18 18:52:04 2017 +0100 +++ b/templates/ops.c Sat Feb 18 20:13:47 2017 +0100 @@ -198,14 +198,16 @@ /* Context-related operations. */ -__attr __test_context(__ref context, __attr attr) +int __test_context_update(__ref context, __attr attr) { + /* Return whether the context should be updated for the attribute. */ + __ref attrcontext = __CONTEXT_AS_VALUE(attr).value; /* Preserve any existing null or instance context. */ if ((attrcontext == 0) || __is_instance(attrcontext)) - return attr; + return 0; /* Test any instance context against the context employed by the attribute. */ @@ -213,7 +215,7 @@ if (__is_instance(context)) { if (__test_common_instance(context, __TYPEPOS(attrcontext), __TYPECODE(attrcontext))) - return __update_context(context, attr); + return 1; else __raise_type_error(); } @@ -221,11 +223,21 @@ /* Test for access to a type class attribute using a type instance. */ if (__test_specific_type(attrcontext, &__TYPE_CLASS_TYPE) && __is_type_instance(context)) - return __update_context(context, attr); + return 1; /* Otherwise, preserve the attribute as retrieved. */ - return attr; + return 0; +} + +__attr __test_context(__ref context, __attr attr) +{ + /* Update the context or return the unchanged attribute. */ + + if (__test_context_update(context, attr)) + return __update_context(context, attr); + else + return attr; } __attr __update_context(__ref context, __attr attr) diff -r 3e5b14c95a55 -r 767f7ac69ef2 templates/ops.h --- a/templates/ops.h Sat Feb 18 18:52:04 2017 +0100 +++ b/templates/ops.h Sat Feb 18 20:13:47 2017 +0100 @@ -70,9 +70,13 @@ /* Context-related operations. */ +int __test_context_update(__ref context, __attr attr); __attr __test_context(__ref context, __attr attr); __attr __update_context(__ref context, __attr attr); +#define __test_context_set(__TARGET, __CONTEXT, __ATTR) \ + (__test_context_update(__CONTEXT, __ATTR) ? (__set_context(__TARGET, (__attr) {.value=__CONTEXT}), __ATTR) : __ATTR) + #define __get_context(__TARGET) (__tmp_contexts[__TARGET]) #define __set_context(__TARGET, __ATTR) (__tmp_contexts[__TARGET] = (__ATTR).value) #define __set_private_context(__ATTR) (__tmp_private_context = (__ATTR).value) diff -r 3e5b14c95a55 -r 767f7ac69ef2 translator.py --- a/translator.py Sat Feb 18 18:52:04 2017 +0100 +++ b/translator.py Sat Feb 18 20:13:47 2017 +0100 @@ -789,6 +789,7 @@ # Mappings to be replaced by those given below. "" : "__tmp_contexts", + "" : "__tmp_contexts", "" : "__tmp_contexts", "" : "__tmp_private_context", "" : "__tmp_value", @@ -797,6 +798,7 @@ self.op_subs = { "" : "__get_context", + "" : "__test_context_set", "" : "__set_context", "" : "__set_private_context", "" : "__set_accessor",