1.1 --- a/docs/concepts.txt Mon Apr 06 01:57:40 2009 +0200
1.2 +++ b/docs/concepts.txt Tue Apr 07 00:57:04 2009 +0200
1.3 @@ -2,8 +2,10 @@
1.4 ========
1.5
1.6 * Contexts and values
1.7 - * Tables and lookups
1.8 + * Tables, attributes and lookups
1.9 * Objects and structures
1.10 + * Parameters and lookups
1.11 + * Instantiation
1.12
1.13 Contexts and Values
1.14 ===================
1.15 @@ -95,8 +97,8 @@
1.16
1.17 See assignment.txt for details.
1.18
1.19 -Tables and Lookups
1.20 -==================
1.21 +Tables, Attributes and Lookups
1.22 +==============================
1.23
1.24 Attribute lookups, where the exact location of an object attribute is deduced,
1.25 are performed differently in micropython than in other implementations.
1.26 @@ -109,15 +111,16 @@
1.27 classes to attribute names. For example:
1.28
1.29 class A:
1.30 - # has attributes x, y
1.31 + # instances have attributes x, y
1.32
1.33 class B(A):
1.34 - # introduces attribute z
1.35 + # introduces attribute z for instances
1.36
1.37 class C:
1.38 - # has attributes a, b, z
1.39 + # instances have attributes a, b, z
1.40
1.41 -This would provide the following table:
1.42 +This would provide the following table, referred to as an object table in the
1.43 +context of classes and instances:
1.44
1.45 Class/attr a b x y z
1.46
1.47 @@ -131,7 +134,7 @@
1.48 the instance or any superclass of the instance's class.
1.49
1.50 The table can be compacted using a representation known as a displacement
1.51 -list:
1.52 +list (referred to as an object list in this context):
1.53
1.54 Classes with attribute offsets
1.55
1.56 @@ -150,6 +153,14 @@
1.57 attributes are defined, whereas the attrcode defines the offset within a
1.58 region of attributes corresponding to a single attribute of a given name.
1.59
1.60 +Attribute Locations
1.61 +-------------------
1.62 +
1.63 +The locations stored in table/list elements are for instance attributes
1.64 +relative to the location of the instance, whereas those for class attributes
1.65 +and modules are absolute addresses (although these could also be changed to
1.66 +object-relative locations).
1.67 +
1.68 Objects and Structures
1.69 ======================
1.70
1.71 @@ -158,7 +169,9 @@
1.72 certain common features and operations are supported in the same way for all
1.73 of these things. To permit this, a common data structure format is used.
1.74
1.75 - Identifier Identifier Address Details Type Object ...
1.76 + Header........................................ Attributes.................
1.77 +
1.78 + Identifier Identifier Address Details Object Object ...
1.79
1.80 0 1 2 3 4 5 6
1.81 classcode attrcode invocation invocation __class__ attribute ...
1.82 @@ -167,23 +180,167 @@
1.83 reference
1.84
1.85 Here, the classcode refers to the attribute lookup table for the object (as
1.86 -described above). Since classes and instances share the same classcode, they
1.87 -might resemble the following:
1.88 +described above). Classes and instances share the same classcode, and their
1.89 +structures reflect this. Functions all belong to the same type and thus employ
1.90 +the classcode for the function built-in type, whereas modules have distinct
1.91 +types since they must support different sets of attributes.
1.92
1.93 Class C:
1.94
1.95 0 1 2 3 4 5 6
1.96 - code for C attrcode __new__ __new__ class type attribute ...
1.97 - for C reference #args, reference reference
1.98 + classcode attrcode __new__ __new__ class type attribute ...
1.99 + for C for C reference #args, reference reference
1.100 defaults
1.101 reference
1.102
1.103 Instance of C:
1.104
1.105 0 1 2 3 4 5 6
1.106 - code for C attrcode C.__call__ C.__call__ class C attribute ...
1.107 - for C reference #args, reference reference
1.108 + classcode attrcode C.__call__ C.__call__ class C attribute ...
1.109 + for C for C reference #args, reference reference
1.110 (if exists) defaults
1.111 reference
1.112
1.113 +Function f:
1.114
1.115 + 0 1 2 3 4 5 6
1.116 + classcode attrcode code code class attribute ...
1.117 + for for reference #args, function (default)
1.118 + function function defaults reference reference
1.119 + reference
1.120 +
1.121 +Module m:
1.122 +
1.123 + 0 1 2 3 4 5 6
1.124 + classcode attrcode (unused) (unused) module type attribute ...
1.125 + for m for m reference (global)
1.126 + reference
1.127 +
1.128 +The __class__ Attribute
1.129 +-----------------------
1.130 +
1.131 +All objects support the __class__ attribute and this is illustrated above with
1.132 +the first attribute.
1.133 +
1.134 +Class: refers to the type class (type.__class__ also refers to the type class)
1.135 +Function: refers to the function class
1.136 +Instance: refers to the class instantiated to make the object
1.137 +
1.138 +Testing Instance Compatibility with Classes (attrcode)
1.139 +------------------------------------------------------
1.140 +
1.141 +Although it would be possible to have a data structure mapping classes to
1.142 +compatible classes, such as a matrix indicating the subclasses (or
1.143 +superclasses) of each class, the need to retain the key to such a data
1.144 +structure for each class might introduce a noticeable overhead.
1.145 +
1.146 +Instead of having a separate structure, descendant classes of each class are
1.147 +inserted as special attributes into the object table. This requires an extra
1.148 +key to be retained, since each class must provide its own attribute code such
1.149 +that upon an instance/class compatibility test, the code may be obtained and
1.150 +used in the object table.
1.151 +
1.152 +Invocation and Code References
1.153 +------------------------------
1.154 +
1.155 +Modules: there is no meaningful invocation reference since modules cannot be
1.156 +explicitly called.
1.157 +
1.158 +Functions: a simple code reference is employed pointing to code implementing
1.159 +the function. Note that the function locals are completely distinct from this
1.160 +structure and are not comparable to attributes. Instead, attributes are
1.161 +reserved for default parameter values, although they do not appear in the
1.162 +object table described above, appearing instead in a separate parameter table
1.163 +described below.
1.164 +
1.165 +Classes: given that classes must be invoked in order to create instances, a
1.166 +reference must be provided in class structures. However, this reference does
1.167 +not point directly at the __init__ method of the class. Instead, the
1.168 +referenced code belongs to a special initialiser function, __new__, consisting
1.169 +of the following instructions:
1.170 +
1.171 + create instance for C
1.172 + call C.__init__(instance, ...)
1.173 + return instance
1.174 +
1.175 +Instances: each instance employs a reference to any __call__ method defined in
1.176 +the class hierarchy for the instance, thus maintaining its callable nature.
1.177 +
1.178 +Both classes and modules may contain code in their definitions - the former in
1.179 +the "body" of the class, potentially defining attributes, and the latter as
1.180 +the "top-level" code in the module, potentially defining attributes/globals -
1.181 +but this code is not associated with any invocation target. It is thus
1.182 +generated in order of appearance and is not referenced externally.
1.183 +
1.184 +Invocation Operation
1.185 +--------------------
1.186 +
1.187 +Consequently, regardless of the object an invocation is always done as
1.188 +follows:
1.189 +
1.190 + get invocation reference from the header
1.191 + jump to reference
1.192 +
1.193 +Additional preparation is necessary before the above code: positional
1.194 +arguments must be saved in the invocation frame, and keyword arguments must be
1.195 +resolved and saved to the appropriate position in the invocation frame.
1.196 +
1.197 +See invocation.txt for details.
1.198 +
1.199 +Parameters and Lookups
1.200 +======================
1.201 +
1.202 +Since Python supports keyword arguments when making invocations, it becomes
1.203 +necessary to record the parameter names associated with each function or
1.204 +method. Just as object tables record attributes positions on classes and
1.205 +instances, parameter tables record parameter positions in function or method
1.206 +parameter lists.
1.207 +
1.208 +For a given program, a parameter table can be considered as being like a
1.209 +matrix mapping functions/methods to parameter names. For example:
1.210 +
1.211 + def f(x, y, z):
1.212 + pass
1.213 +
1.214 + def g(a, b, c):
1.215 + pass
1.216 +
1.217 + def h(a, x):
1.218 + pass
1.219 +
1.220 +This would provide the following table, referred to as a parameter table in
1.221 +the context of functions and methods:
1.222 +
1.223 + Function/param a b c x y z
1.224 +
1.225 + f 1 2 3
1.226 + g 1 2 3
1.227 + h 1 2
1.228 +
1.229 +Just as with parameter tables, a displacement list can be prepared from a
1.230 +parameter table:
1.231 +
1.232 + Functions with parameter (attribute) offsets
1.233 +
1.234 + funccode f
1.235 + attrcode a b c x y z
1.236 +
1.237 + g
1.238 + a b c x y z
1.239 +
1.240 + h
1.241 + a b c x y z
1.242 +
1.243 + List . . . 1 2 3 1 2 3 1 . . 2 . .
1.244 +
1.245 +Here, the funccode refers to the offset in the list at which a function's
1.246 +parameters are defined, whereas the attrcode defines the offset within a
1.247 +region of attributes corresponding to a single parameter of a given name.
1.248 +
1.249 +Instantiation
1.250 +=============
1.251 +
1.252 +When instantiating classes, memory must be reserved for the header of the
1.253 +resulting instance, along with locations for the attributes of the instance.
1.254 +Since the instance header contains data common to all instances of a class, a
1.255 +template header is copied to the start of the newly reserved memory region.
2.1 --- a/docs/structures.txt Mon Apr 06 01:57:40 2009 +0200
2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3 @@ -1,116 +0,0 @@
2.4 -Data Structures
2.5 -===============
2.6 -
2.7 -The __class__ Attribute
2.8 ------------------------
2.9 -
2.10 -All objects support the __class__ attribute:
2.11 -
2.12 -Class: refers to the type class (type.__class__ also refers to the type class)
2.13 -Function: refers to the function class
2.14 -Instance: refers to the class instantiated to make the object
2.15 -
2.16 -Invocation
2.17 -----------
2.18 -
2.19 -The following actions need to be supported:
2.20 -
2.21 -Class: create instance, call __init__ with instance, return object
2.22 -Function: call function body, return result
2.23 -Instance: call __call__ method, return result
2.24 -
2.25 -Structure Layout
2.26 -----------------
2.27 -
2.28 -The __new__ reference would lead to code consisting of the following
2.29 -instructions:
2.30 -
2.31 - create instance for C
2.32 - call C.__init__(instance, ...)
2.33 - return instance
2.34 -
2.35 -If C has a __call__ attribute, the invocation "slot" of C instances would
2.36 -refer to the same thing as C.__call__. This "slot" has to be prepared when
2.37 -creating instances, either by modifying the sequence of instructions used in,
2.38 -amongst other places, the instantiator function, or by generating a template
2.39 -instance whose details are copied when new instances are created.
2.40 -
2.41 -For functions, the same general layout applies:
2.42 -
2.43 -Function f:
2.44 -
2.45 - 0 1 2 3 4 5 6
2.46 - code for attrcode code code class attribute ...
2.47 - function for reference #args, function (default)
2.48 - function defaults reference reference
2.49 - reference
2.50 -
2.51 -Here, the code reference would lead to code for the function. Note that the
2.52 -function locals are completely distinct from this structure and are not
2.53 -comparable to attributes. Instead, attributes are reserved for default
2.54 -parameter values.
2.55 -
2.56 -For modules, there is no meaningful invocation reference:
2.57 -
2.58 -Module m:
2.59 -
2.60 - 0 1 2 3 4 5 6
2.61 - code for m attrcode (unused) (unused) module type attribute ...
2.62 - for m reference (global)
2.63 - reference
2.64 -
2.65 -Both classes and modules have code in their definitions, but this would be
2.66 -generated in order and not referenced externally.
2.67 -
2.68 -Invocation Operation
2.69 ---------------------
2.70 -
2.71 -Consequently, regardless of the object an invocation is always done as
2.72 -follows:
2.73 -
2.74 - get invocation reference (at object+1)
2.75 - jump to reference
2.76 -
2.77 -Additional preparation is necessary before the above code: positional
2.78 -arguments must be saved to the parameter stack, and keyword arguments must be
2.79 -resolved and saved to the appropriate position in the parameter stack.
2.80 -
2.81 -Attribute Operations
2.82 ---------------------
2.83 -
2.84 -Attribute access needs to go through the attribute lookup table. Some
2.85 -optimisations are possible and are described in the appropriate section.
2.86 -
2.87 -One important aspect of attribute access is the appropriate setting of the
2.88 -context in the acquired attribute value. From the table describing the
2.89 -acquisition of values, it is clear that the principal exception is that where
2.90 -a class-originating attribute is accessed on an instance. Consequently, the
2.91 -following algorithm could be employed once an attribute has been located:
2.92 -
2.93 - 1. If the attribute's context is a special value, indicating that it should
2.94 - be replaced upon instance access, then proceed to the next step;
2.95 - otherwise, acquire both the context and the object as they are.
2.96 -
2.97 - 2. If the accessor is an instance, use that as the value's context, acquiring
2.98 - only the object from the attribute.
2.99 -
2.100 -Where accesses can be determined ahead of time (as discussed in the
2.101 -optimisations section), the above algorithm may not necessarily be employed in
2.102 -the generated code for some accesses.
2.103 -
2.104 -Instance/Class Compatibility
2.105 -----------------------------
2.106 -
2.107 -Although it would be possible to have a data structure mapping classes to
2.108 -compatible classes, which in the case of context (or self argument)
2.109 -suitability in invocations would involve a mapping from a class to itself plus
2.110 -its descendants, the need to retain the key to such a data structure for each
2.111 -class might introduce a noticeable overhead. Such a structure would
2.112 -effectively be a matrix with each dimension indexed using the same sequence of
2.113 -codes for each of the classes in a program.
2.114 -
2.115 -The current solution is to insert descendants as special attributes into the
2.116 -object/attribute lookup table. This requires an extra key to be retained,
2.117 -since each class must provide its own attribute code such that upon an
2.118 -instance/class compatibility test, the code may be obtained and used in the
2.119 -object table.
4.1 --- a/micropython/data.py Mon Apr 06 01:57:40 2009 +0200
4.2 +++ b/micropython/data.py Tue Apr 07 00:57:04 2009 +0200
4.3 @@ -499,7 +499,7 @@
4.4 classcode = objtable.as_list().get_code(self.full_name())
4.5 attrcode = objtable.get_index(self.full_name())
4.6
4.7 - # Append a template of an instance for use when instantiating classes.
4.8 + # Include a template of an instance for use when instantiating classes.
4.9
4.10 call_method = self.get("__call__")
4.11 call_method_value = call_method and call_method.get_value()
4.12 @@ -510,6 +510,9 @@
4.13 instantiator_code_location = self.get_instantiator().blocks[0].location
4.14
4.15 return [
4.16 +
4.17 + # Template instance...
4.18 +
4.19 DataObject(
4.20 classcode, attrcode, call_method_code_location,
4.21 (
4.22 @@ -519,6 +522,9 @@
4.23 1,
4.24 self.full_name()
4.25 ),
4.26 +
4.27 + # Class...
4.28 +
4.29 DataObject(
4.30 classcode, attrcode, instantiator_code_location,
4.31 (