1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/docs/structures.txt Sun Jul 27 02:00:31 2008 +0200
1.3 @@ -0,0 +1,203 @@
1.4 +Data Structures
1.5 +===============
1.6 +
1.7 +The fundamental "value type" is a pair of references: one pointing to the
1.8 +referenced object represented by the interchangeable value; one referring to
1.9 +the context of the referenced object, typically the object through which the
1.10 +referenced object was acquired as an attribute.
1.11 +
1.12 +Value Layout
1.13 +------------
1.14 +
1.15 + 0 1
1.16 + object context
1.17 + reference reference
1.18 +
1.19 +Acquiring Values
1.20 +----------------
1.21 +
1.22 +Values are acquired through name lookups and attribute access, yielding
1.23 +the appropriate object reference together with a context reference as
1.24 +indicated in the following table:
1.25 +
1.26 + Type of Access Context Notes
1.27 + -------------- ------- -----
1.28 +
1.29 + Local name Preserved Functions provide no context
1.30 +
1.31 + Global name Preserved Modules provide no context
1.32 +
1.33 + Class-originating Accessor Class accessor preserves the stored
1.34 + attribute -or- context; instance accessor overrides
1.35 + Preserved the stored context if it is null or
1.36 + belongs to the instance's class
1.37 + hierarchy
1.38 +
1.39 + Instance-originating Preserved Methods retain their original context
1.40 + attribute
1.41 +
1.42 +There may be some scope for simplifying the above, to the detriment of Python
1.43 +compatibility, since the unbound vs. bound methods situation can be confusing.
1.44 +
1.45 +Manipulating Values
1.46 +-------------------
1.47 +
1.48 +According to the table describing value acquisition, different instructions
1.49 +must implement different operations when acquiring values:
1.50 +
1.51 + Instruction Purpose Context Operations
1.52 + ----------- ------- ------------------
1.53 +
1.54 + LoadConst Load class, function, Combine null context with loaded
1.55 + module, constant object
1.56 +
1.57 + LoadAddress Load attribute from Classes, functions and modules
1.58 + known object stored as cause the loaded attribute to be
1.59 + an attribute retrieved unchanged; whereas
1.60 + constants (representing instances)
1.61 + cause the constant to override the
1.62 + attribute's own context (since all
1.63 + attributes should belong to the
1.64 + constant's class hierarchy)
1.65 +
1.66 + LoadAttr Load attribute from Attributes with null contexts or
1.67 + instance stored as an contexts compatible with the
1.68 + attribute instance cause loaded attributes
1.69 + to combine the instance as context
1.70 + with the object from the
1.71 + attribute; other attributes have
1.72 + their context preserved
1.73 +
1.74 + LoadAttrIndex Load attribute from Classes, functions and modules as
1.75 + unknown object stored the unknown object accessor cause
1.76 + as an attribute the loaded attribute to be
1.77 + retrieved unchanged; whereas
1.78 + instances cause the LoadAttr rules
1.79 + to apply
1.80 +
1.81 +Consequently, a certain amount of run-time testing is required for both
1.82 +LoadAttr and LoadAttrIndex.
1.83 +
1.84 +Objects
1.85 +-------
1.86 +
1.87 +Since classes, functions and instances are all "objects", each must support
1.88 +certain features and operations in the same way.
1.89 +
1.90 +The __class__ Attribute
1.91 +-----------------------
1.92 +
1.93 +All objects support the __class__ attribute:
1.94 +
1.95 +Class: refers to the type class (type.__class__ also refers to the type class)
1.96 +Function: refers to the function class
1.97 +Instance: refers to the class instantiated to make the object
1.98 +
1.99 +Invocation
1.100 +----------
1.101 +
1.102 +The following actions need to be supported:
1.103 +
1.104 +Class: create instance, call __init__ with instance, return object
1.105 +Function: call function body, return result
1.106 +Instance: call __call__ method, return result
1.107 +
1.108 +Structure Layout
1.109 +----------------
1.110 +
1.111 +A suitable structure layout might be something like this:
1.112 +
1.113 + Identifier Address Type Object ...
1.114 +
1.115 + 0 1 2 3 4
1.116 + classcode invocation __class__ attribute ...
1.117 + reference reference reference
1.118 +
1.119 +Here, the classcode refers to the attribute lookup table for the object. Since
1.120 +classes and instances share the same classcode, they might resemble the
1.121 +following:
1.122 +
1.123 +Class C:
1.124 +
1.125 + 0 1 2 3 4
1.126 + code for C __new__ class type attribute ...
1.127 + reference reference reference
1.128 +
1.129 +Instance of C:
1.130 +
1.131 + 0 1 2 3 4
1.132 + code for C C.__call__ class C attribute ...
1.133 + reference reference reference
1.134 + (if exists)
1.135 +
1.136 +The __new__ reference would lead to code consisting of the following
1.137 +instructions:
1.138 +
1.139 + create instance for C
1.140 + call C.__init__(instance, ...)
1.141 + return instance
1.142 +
1.143 +If C has a __call__ attribute, the invocation "slot" of C instances would
1.144 +refer to the same thing as C.__call__.
1.145 +
1.146 +For functions, the same general layout applies:
1.147 +
1.148 +Function f:
1.149 +
1.150 + 0 1 2 3 4
1.151 + code for code class attribute ...
1.152 + function reference function reference
1.153 + reference
1.154 +
1.155 +Here, the code reference would lead to code for the function. Note that the
1.156 +function locals are completely distinct from this structure and are not
1.157 +comparable to attributes. Instead, attributes are reserved for default
1.158 +parameter values.
1.159 +
1.160 +For modules, there is no meaningful invocation reference:
1.161 +
1.162 +Module m:
1.163 +
1.164 + 0 1 2 3 4
1.165 + code for m (unused) module type attribute ...
1.166 + reference (global)
1.167 + reference
1.168 +
1.169 +Both classes and modules have code in their definitions, but this would be
1.170 +generated in order and not referenced externally.
1.171 +
1.172 +Invocation Operation
1.173 +--------------------
1.174 +
1.175 +Consequently, regardless of the object an invocation is always done as
1.176 +follows:
1.177 +
1.178 + get invocation reference (at object+1)
1.179 + jump to reference
1.180 +
1.181 +Additional preparation is necessary before the above code: positional
1.182 +arguments must be saved to the parameter stack, and keyword arguments must be
1.183 +resolved and saved to the appropriate position in the parameter stack.
1.184 +
1.185 +Attribute Operations
1.186 +--------------------
1.187 +
1.188 +Attribute access needs to go through the attribute lookup table. Some
1.189 +optimisations are possible and are described in the appropriate section.
1.190 +
1.191 +One important aspect of attribute access is the appropriate setting of the
1.192 +context in the acquired attribute value. From the table describing the
1.193 +acquisition of values, it is clear that the principal exception is that where
1.194 +a class-originating attribute is accessed on an instance. Consequently, the
1.195 +following algorithm could be employed once an attribute has been located:
1.196 +
1.197 + 1. If the attribute's context is a special value, indicating that it should
1.198 + be replaced upon instance access, then proceed to the next step;
1.199 + otherwise, acquire both the context and the object as they are.
1.200 +
1.201 + 2. If the accessor is an instance, use that as the value's context, acquiring
1.202 + only the object from the attribute.
1.203 +
1.204 +Where accesses can be determined ahead of time (as discussed in the
1.205 +optimisations section), the above algorithm may not necessarily be employed in
1.206 +the generated code for some accesses.