1.1 --- a/README.txt Thu Jan 24 01:38:08 2008 +0100
1.2 +++ b/README.txt Mon Jan 28 01:15:01 2008 +0100
1.3 @@ -171,6 +171,23 @@
1.4 Optimisations
1.5 =============
1.6
1.7 +Some optimisations around constant objects might be possible; these depend on
1.8 +the following:
1.9 +
1.10 + * Reliable tracking of assignments: where assignment operations occur, the
1.11 + target of the assignment should be determined if any hope of optimisation
1.12 + is to be maintained. Where no guarantees can be made about the target of
1.13 + an assignment, no assignment-related information should be written to
1.14 + potential targets.
1.15 +
1.16 + * Objects acting as "containers" of attributes must be regarded as "safe":
1.17 + where assignments are recorded as occurring on an attribute, it must be
1.18 + guaranteed that no other unforeseen ways exist to assign to such
1.19 + attributes.
1.20 +
1.21 +The discussion below presents certain rules which must be imposed to uphold
1.22 +the above requirements.
1.23 +
1.24 Constant Attributes
1.25 -------------------
1.26
1.27 @@ -185,7 +202,7 @@
1.28
1.29 another_module.this_module.attr = value
1.30
1.31 - (Where this_module is a reference to the current module.)
1.32 + In the above, this_module is a reference to the current module.
1.33
1.34 2. For classes, provided that assignments to class attributes are only
1.35 permitted within the class definition, outside methods. This would mean
1.36 @@ -204,16 +221,61 @@
1.37 run-time details of the "container" and the compile-time details of the
1.38 attribute) with a LoadAttr instruction.
1.39
1.40 +Additional Controls
1.41 +-------------------
1.42 +
1.43 +For the above cases for "container" objects, the following controls would need
1.44 +to apply:
1.45 +
1.46 + 1. Modules would need to be immutable after initialisation. However, during
1.47 + initialisation, there remains a possibility of another module attempting
1.48 + to access the original module. For example, if ppp/__init__.py contained
1.49 + the following...
1.50 +
1.51 + x = 1
1.52 + import ppp.qqq
1.53 + print x
1.54 +
1.55 + ...and if ppp/qqq.py contained the following...
1.56 +
1.57 + import ppp
1.58 + ppp.x = 2
1.59 +
1.60 + ...then the value 2 would be printed. Since modules are objects which are
1.61 + registered globally in a program, it would be possible to set attributes
1.62 + in the above way.
1.63 +
1.64 + 2. Classes would need to be immutable after initialisation. However, since
1.65 + classes are objects, any reference to a class after initialisation could
1.66 + be used to set attributes on the class.
1.67 +
1.68 +Solutions:
1.69 +
1.70 + 1. Insist on global scope for module attribute assignments.
1.71 +
1.72 + 2. Insist on local scope within classes.
1.73 +
1.74 +Both of the above measures need to be enforced at run-time, since an arbitrary
1.75 +attribute assignment could be attempted on any kind of object, yet to uphold
1.76 +the properties of "safe containers", attempts to change attributes of such
1.77 +objects should be denied. Since foreseen attribute assignment operations have
1.78 +certain properties detectable at compile-time, it could be appropriate to
1.79 +generate special instructions (or modified instructions) during the
1.80 +initialisation of modules and classes for such foreseen assignments, whilst
1.81 +employing normal attribute assignment operations in all other cases. Indeed,
1.82 +the StoreAttr instruction, which is used to set attributes in "safe
1.83 +containers" would be used exclusively for this purpose; the StoreAttrIndex
1.84 +instruction would be used exclusively for all other attribute assignments.
1.85 +
1.86 Constant Attribute Values
1.87 -------------------------
1.88
1.89 -Where an attribute value is itself constant and be used either in an operation
1.90 -accessing its own attributes, or in an invocation, the value can be directly
1.91 -inspected for optimisations or employed in the generated code. For the
1.92 -attribute values themselves, only objects of a constant nature may be
1.93 +Where an attribute value is itself regarded as constant, is a "safe container"
1.94 +and is used in an operation accessing its own attributes, the value can be
1.95 +directly inspected for optimisations or employed in the generated code. For
1.96 +the attribute values themselves, only objects of a constant nature may be
1.97 considered suitable for this particular optimisation:
1.98
1.99 - * Functions
1.100 * Classes
1.101 * Modules
1.102 * Instances defined as constant literals
1.103 @@ -221,3 +283,53 @@
1.104 This is because arbitrary objects (such as most instances) have no
1.105 well-defined form before run-time and cannot be investigated further at
1.106 compile-time or have a representation inserted into the generated code.
1.107 +
1.108 +Class Attributes and Access via Instances
1.109 +-----------------------------------------
1.110 +
1.111 +Unlike module attributes, class attributes can be accessed in a number of
1.112 +different ways:
1.113 +
1.114 + * Using the class itself:
1.115 +
1.116 + C.x = 123
1.117 + cls = C; cls.x = 234
1.118 +
1.119 + * Using a subclass of the class (for reading attributes):
1.120 +
1.121 + class D(C):
1.122 + pass
1.123 + D.x # setting D.x would populate D, not C
1.124 +
1.125 + * Using instances of the class or a subclass of the class (for reading
1.126 + attributes):
1.127 +
1.128 + c = C()
1.129 + c.x # setting c.x would populate c, not C
1.130 +
1.131 +Since assignments are only achieved using direct references to the class, and
1.132 +since class attributes should be defined only within the class initialisation
1.133 +process, the properties of class attributes should be consistent with those
1.134 +desired.
1.135 +
1.136 +Method Access via Instances
1.137 +---------------------------
1.138 +
1.139 +It is desirable to optimise method access, even though most method calls are
1.140 +likely to occur via instances. It is possible, given the properties of methods
1.141 +as class attributes to investigate the kind of instance that the self
1.142 +parameter/local refers to within each method: it should be an instance either
1.143 +of the class in which the method is defined or a compatible class, although
1.144 +situations exist where this might not be the case:
1.145 +
1.146 + * Explicit invocation of a method:
1.147 +
1.148 + d = D() # D is not related to C
1.149 + C.f(d) # calling f(self) in C
1.150 +
1.151 +Optimising Function Invocations
1.152 +-------------------------------
1.153 +
1.154 +Where an attribute value is itself regarded as constant and is a function,
1.155 +knowledge about the parameters of the function can be employed to optimise the
1.156 +preparation of the invocation frame.