paul@199 | 1 | Concepts
|
paul@199 | 2 | ========
|
paul@199 | 3 |
|
paul@199 | 4 | * Contexts and values
|
paul@199 | 5 | * Tables and lookups
|
paul@199 | 6 | * Objects and structures
|
paul@199 | 7 |
|
paul@199 | 8 | Contexts and Values
|
paul@199 | 9 | ===================
|
paul@199 | 10 |
|
paul@199 | 11 | Values are used as the common reference representation in micropython: as
|
paul@199 | 12 | stored representations of attributes (of classes, instances, modules, and
|
paul@199 | 13 | other objects supporting attribute-like entities) as well as the stored values
|
paul@199 | 14 | associated with names in functions and methods.
|
paul@199 | 15 |
|
paul@199 | 16 | Unlike other implementations, micropython does not create things like bound
|
paul@199 | 17 | method objects for individual instances. Instead, all objects are referenced
|
paul@199 | 18 | using a context, reference pair:
|
paul@199 | 19 |
|
paul@199 | 20 | Value Layout
|
paul@199 | 21 | ------------
|
paul@199 | 22 |
|
paul@199 | 23 | 0 1
|
paul@199 | 24 | context object
|
paul@199 | 25 | reference reference
|
paul@199 | 26 |
|
paul@199 | 27 | Specific implementations might reverse this ordering for optimisation
|
paul@199 | 28 | purposes.
|
paul@199 | 29 |
|
paul@199 | 30 | Rationale
|
paul@199 | 31 | ---------
|
paul@199 | 32 |
|
paul@199 | 33 | To reduce the number of created objects whilst retaining the ability to
|
paul@199 | 34 | support bound method invocations. The context indicates the context in which
|
paul@199 | 35 | an invocation is performed, typically the owner of the method.
|
paul@199 | 36 |
|
paul@199 | 37 | Usage
|
paul@199 | 38 | -----
|
paul@199 | 39 |
|
paul@199 | 40 | The context may be inserted as the first argument when a value is involved in
|
paul@199 | 41 | an invocation. This argument may then be omitted from the invocation if its
|
paul@199 | 42 | usage is not appropriate.
|
paul@199 | 43 |
|
paul@199 | 44 | See invocation.txt for details.
|
paul@199 | 45 |
|
paul@199 | 46 | Contexts in Acquired Values
|
paul@199 | 47 | ---------------------------
|
paul@199 | 48 |
|
paul@199 | 49 | There are two classes of instructions which provide values:
|
paul@199 | 50 |
|
paul@199 | 51 | Instruction Purpose Context Operations
|
paul@199 | 52 | ----------- ------- ------------------
|
paul@199 | 53 |
|
paul@199 | 54 | LoadConst Load class, function, Combine null context with
|
paul@199 | 55 | module, constant loaded object
|
paul@199 | 56 |
|
paul@199 | 57 | LoadAddress Load attribute from Preserve or override stored
|
paul@199 | 58 | LoadAddressContext class, module, context (as described in
|
paul@199 | 59 | LoadAttr instance assignment.txt)
|
paul@199 | 60 | LoadAttrIndex
|
paul@199 | 61 |
|
paul@199 | 62 | In order to comply with traditional Python behaviour, contexts may or may not
|
paul@199 | 63 | represent the object from which an attribute has been acquired.
|
paul@199 | 64 |
|
paul@199 | 65 | See assignment.txt for details.
|
paul@199 | 66 |
|
paul@199 | 67 | Contexts in Stored Values
|
paul@199 | 68 | -------------------------
|
paul@199 | 69 |
|
paul@199 | 70 | There is only one class of instruction for storing values:
|
paul@199 | 71 |
|
paul@199 | 72 | Instruction Purpose Context Operations
|
paul@199 | 73 | ----------- ------- ------------------
|
paul@199 | 74 |
|
paul@199 | 75 | StoreAddress Store attribute in a Preserve context; note that no
|
paul@199 | 76 | known object test for class attribute
|
paul@199 | 77 | assignment should be necessary
|
paul@199 | 78 | since this instruction should only
|
paul@199 | 79 | be generated for module globals
|
paul@199 | 80 |
|
paul@199 | 81 | StoreAttr Store attribute in an Preserve context; note that no
|
paul@199 | 82 | instance test for class attribute
|
paul@199 | 83 | assignment should be necessary
|
paul@199 | 84 | since this instruction should only
|
paul@199 | 85 | be generated for self accesses
|
paul@199 | 86 |
|
paul@199 | 87 | StoreAttrIndex Store attribute in an Preserve context; since the index
|
paul@199 | 88 | unknown object lookup could yield a class
|
paul@199 | 89 | attribute, a test of the nature of
|
paul@199 | 90 | the nature of the structure is
|
paul@199 | 91 | necessary in order to prevent
|
paul@199 | 92 | assignments to classes
|
paul@199 | 93 |
|
paul@199 | 94 | Note that contexts are never changed in the stored value: they are preserved.
|
paul@199 | 95 |
|
paul@199 | 96 | See assignment.txt for details.
|
paul@199 | 97 |
|
paul@199 | 98 | Tables and Lookups
|
paul@199 | 99 | ==================
|
paul@199 | 100 |
|
paul@199 | 101 | Attribute lookups, where the exact location of an object attribute is deduced,
|
paul@199 | 102 | are performed differently in micropython than in other implementations.
|
paul@199 | 103 | Instead of providing attribute dictionaries, in which attributes are found,
|
paul@199 | 104 | attributes are located at fixed places in object structures (described below)
|
paul@199 | 105 | and their locations are stored using a special representation known as a
|
paul@199 | 106 | table.
|
paul@199 | 107 |
|
paul@199 | 108 | For a given program, a table can be considered as being like a matrix mapping
|
paul@199 | 109 | classes to attribute names. For example:
|
paul@199 | 110 |
|
paul@199 | 111 | class A:
|
paul@199 | 112 | # has attributes x, y
|
paul@199 | 113 |
|
paul@199 | 114 | class B(A):
|
paul@199 | 115 | # introduces attribute z
|
paul@199 | 116 |
|
paul@199 | 117 | class C:
|
paul@199 | 118 | # has attributes a, b, z
|
paul@199 | 119 |
|
paul@199 | 120 | This would provide the following table:
|
paul@199 | 121 |
|
paul@199 | 122 | Class/attr a b x y z
|
paul@199 | 123 |
|
paul@199 | 124 | A 1 2
|
paul@199 | 125 | B 1 2 3
|
paul@199 | 126 | C 1 2 3
|
paul@199 | 127 |
|
paul@199 | 128 | A limitation of this representation is that instance attributes may not shadow
|
paul@199 | 129 | class attributes: if an attribute with a given name is not defined on an
|
paul@199 | 130 | instance, an attribute with the same name cannot be provided by the class of
|
paul@199 | 131 | the instance or any superclass of the instance's class.
|
paul@199 | 132 |
|
paul@199 | 133 | The table can be compacted using a representation known as a displacement
|
paul@199 | 134 | list:
|
paul@199 | 135 |
|
paul@199 | 136 | Classes with attribute offsets
|
paul@199 | 137 |
|
paul@199 | 138 | classcode A
|
paul@199 | 139 | attrcode a b x y z
|
paul@199 | 140 |
|
paul@199 | 141 | B
|
paul@199 | 142 | a b x y z
|
paul@199 | 143 |
|
paul@199 | 144 | C
|
paul@199 | 145 | a b x y z
|
paul@199 | 146 |
|
paul@199 | 147 | List . . 1 2 1 2 3 1 2 . . 3
|
paul@199 | 148 |
|
paul@199 | 149 | Here, the classcode refers to the offset in the list at which a class's
|
paul@199 | 150 | attributes are defined, whereas the attrcode defines the offset within a
|
paul@199 | 151 | region of attributes corresponding to a single attribute of a given name.
|
paul@199 | 152 |
|
paul@199 | 153 | Objects and Structures
|
paul@199 | 154 | ======================
|
paul@199 | 155 |
|
paul@199 | 156 | As well as references, micropython needs to have actual objects to refer to.
|
paul@199 | 157 | Since classes, functions and instances are all objects, it is desirable that
|
paul@199 | 158 | certain common features and operations are supported in the same way for all
|
paul@199 | 159 | of these things. To permit this, a common data structure format is used.
|
paul@199 | 160 |
|
paul@199 | 161 | Identifier Identifier Address Details Type Object ...
|
paul@199 | 162 |
|
paul@199 | 163 | 0 1 2 3 4 5 6
|
paul@199 | 164 | classcode attrcode invocation invocation __class__ attribute ...
|
paul@199 | 165 | reference #args, reference reference
|
paul@199 | 166 | defaults
|
paul@199 | 167 | reference
|
paul@199 | 168 |
|
paul@199 | 169 | Here, the classcode refers to the attribute lookup table for the object (as
|
paul@199 | 170 | described above). Since classes and instances share the same classcode, they
|
paul@199 | 171 | might resemble the following:
|
paul@199 | 172 |
|
paul@199 | 173 | Class C:
|
paul@199 | 174 |
|
paul@199 | 175 | 0 1 2 3 4 5 6
|
paul@199 | 176 | code for C attrcode __new__ __new__ class type attribute ...
|
paul@199 | 177 | for C reference #args, reference reference
|
paul@199 | 178 | defaults
|
paul@199 | 179 | reference
|
paul@199 | 180 |
|
paul@199 | 181 | Instance of C:
|
paul@199 | 182 |
|
paul@199 | 183 | 0 1 2 3 4 5 6
|
paul@199 | 184 | code for C attrcode C.__call__ C.__call__ class C attribute ...
|
paul@199 | 185 | for C reference #args, reference reference
|
paul@199 | 186 | (if exists) defaults
|
paul@199 | 187 | reference
|
paul@199 | 188 |
|
paul@199 | 189 |
|