micropython

Annotated docs/concepts.txt

219:b58aae0af656
2009-05-22 Paul Boddie Removed the codedetails attribute from DataObject instances and from the structure descriptions. Added notes about argument checking for CheckFrame since the context needs to be verified where it is required. Made sure that the bool class is available since True and False are always available and their methods must also be accessible via the object table. Split various tests into separate programs with improved labelling.
paul@199 1
Concepts
paul@199 2
========
paul@199 3
paul@201 4
This document describes the underlying concepts employed in micropython.
paul@201 5
paul@201 6
  * Namespaces and attribute definition
paul@199 7
  * Contexts and values
paul@200 8
  * Tables, attributes and lookups
paul@199 9
  * Objects and structures
paul@200 10
  * Parameters and lookups
paul@200 11
  * Instantiation
paul@199 12
paul@201 13
Namespaces and Attribute Definition
paul@201 14
===================================
paul@201 15
paul@201 16
Namespaces are any objects which can retain attributes.
paul@201 17
paul@201 18
  * Module attributes are defined either at the module level or by global
paul@201 19
    statements.
paul@201 20
  * Class attributes are defined only within class statements.
paul@201 21
  * Instance attributes are defined only by assignments to attributes of self
paul@201 22
    within __init__ methods.
paul@201 23
paul@201 24
These restrictions apply because such attributes are thus explicitly declared,
paul@201 25
permitting the use of tables (described below). Module and class attributes
paul@201 26
can also be finalised in this way in order to permit certain optimisations.
paul@201 27
paul@201 28
See rejected.txt for complicating mechanisms which could be applied to
paul@201 29
mitigate the effects of these restrictions on optimisations.
paul@201 30
paul@199 31
Contexts and Values
paul@199 32
===================
paul@199 33
paul@199 34
Values are used as the common reference representation in micropython: as
paul@199 35
stored representations of attributes (of classes, instances, modules, and
paul@199 36
other objects supporting attribute-like entities) as well as the stored values
paul@199 37
associated with names in functions and methods.
paul@199 38
paul@199 39
Unlike other implementations, micropython does not create things like bound
paul@199 40
method objects for individual instances. Instead, all objects are referenced
paul@199 41
using a context, reference pair:
paul@199 42
paul@199 43
Value Layout
paul@199 44
------------
paul@199 45
paul@199 46
    0           1
paul@199 47
    context     object
paul@199 48
    reference   reference
paul@199 49
paul@199 50
Specific implementations might reverse this ordering for optimisation
paul@199 51
purposes.
paul@199 52
paul@199 53
Rationale
paul@199 54
---------
paul@199 55
paul@199 56
To reduce the number of created objects whilst retaining the ability to
paul@199 57
support bound method invocations. The context indicates the context in which
paul@199 58
an invocation is performed, typically the owner of the method.
paul@199 59
paul@199 60
Usage
paul@199 61
-----
paul@199 62
paul@199 63
The context may be inserted as the first argument when a value is involved in
paul@199 64
an invocation. This argument may then be omitted from the invocation if its
paul@199 65
usage is not appropriate.
paul@199 66
paul@199 67
See invocation.txt for details.
paul@199 68
paul@199 69
Contexts in Acquired Values
paul@199 70
---------------------------
paul@199 71
paul@199 72
There are two classes of instructions which provide values:
paul@199 73
paul@199 74
    Instruction         Purpose                 Context Operations
paul@199 75
    -----------         -------                 ------------------
paul@199 76
paul@199 77
    LoadConst           Load class, function,   Combine null context with
paul@199 78
                        module, constant        loaded object
paul@199 79
paul@201 80
    LoadAddress*        Load attribute from     Preserve or override stored
paul@201 81
    LoadAttr*           class, module,          context (as described in
paul@201 82
                        instance                assignment.txt)
paul@199 83
paul@199 84
In order to comply with traditional Python behaviour, contexts may or may not
paul@199 85
represent the object from which an attribute has been acquired.
paul@199 86
paul@199 87
See assignment.txt for details.
paul@199 88
paul@199 89
Contexts in Stored Values
paul@199 90
-------------------------
paul@199 91
paul@199 92
There is only one class of instruction for storing values:
paul@199 93
paul@199 94
    Instruction     Purpose                 Context Operations
paul@199 95
    -----------     -------                 ------------------
paul@199 96
paul@199 97
    StoreAddress    Store attribute in a    Preserve context; note that no
paul@199 98
                    known object            test for class attribute
paul@199 99
                                            assignment should be necessary
paul@199 100
                                            since this instruction should only
paul@199 101
                                            be generated for module globals
paul@199 102
paul@199 103
    StoreAttr       Store attribute in an   Preserve context; note that no
paul@199 104
                    instance                test for class attribute
paul@199 105
                                            assignment should be necessary
paul@199 106
                                            since this instruction should only
paul@199 107
                                            be generated for self accesses
paul@199 108
paul@199 109
    StoreAttrIndex  Store attribute in an   Preserve context; since the index
paul@199 110
                    unknown object          lookup could yield a class
paul@199 111
                                            attribute, a test of the nature of
paul@199 112
                                            the nature of the structure is
paul@199 113
                                            necessary in order to prevent
paul@199 114
                                            assignments to classes
paul@199 115
paul@199 116
Note that contexts are never changed in the stored value: they are preserved.
paul@199 117
paul@199 118
See assignment.txt for details.
paul@199 119
paul@200 120
Tables, Attributes and Lookups
paul@200 121
==============================
paul@199 122
paul@199 123
Attribute lookups, where the exact location of an object attribute is deduced,
paul@199 124
are performed differently in micropython than in other implementations.
paul@199 125
Instead of providing attribute dictionaries, in which attributes are found,
paul@199 126
attributes are located at fixed places in object structures (described below)
paul@199 127
and their locations are stored using a special representation known as a
paul@199 128
table.
paul@199 129
paul@199 130
For a given program, a table can be considered as being like a matrix mapping
paul@199 131
classes to attribute names. For example:
paul@199 132
paul@199 133
    class A:
paul@200 134
        # instances have attributes x, y
paul@199 135
paul@199 136
    class B(A):
paul@200 137
        # introduces attribute z for instances
paul@199 138
paul@199 139
    class C:
paul@200 140
        # instances have attributes a, b, z
paul@199 141
paul@200 142
This would provide the following table, referred to as an object table in the
paul@200 143
context of classes and instances:
paul@199 144
paul@199 145
    Class/attr      a   b   x   y   z
paul@199 146
paul@199 147
    A                       1   2
paul@199 148
    B                       1   2   3
paul@199 149
    C               1   2           3
paul@199 150
paul@199 151
A limitation of this representation is that instance attributes may not shadow
paul@199 152
class attributes: if an attribute with a given name is not defined on an
paul@199 153
instance, an attribute with the same name cannot be provided by the class of
paul@199 154
the instance or any superclass of the instance's class.
paul@199 155
paul@199 156
The table can be compacted using a representation known as a displacement
paul@200 157
list (referred to as an object list in this context):
paul@199 158
paul@199 159
                Classes with attribute offsets
paul@199 160
paul@199 161
    classcode   A
paul@199 162
    attrcode    a   b   x   y   z
paul@199 163
paul@199 164
                        B
paul@199 165
                        a   b   x   y   z
paul@199 166
paul@199 167
                                            C
paul@199 168
                                            a   b   x   y   z
paul@199 169
paul@199 170
    List        .   .   1   2   1   2   3   1   2   .   .   3
paul@199 171
paul@199 172
Here, the classcode refers to the offset in the list at which a class's
paul@199 173
attributes are defined, whereas the attrcode defines the offset within a
paul@199 174
region of attributes corresponding to a single attribute of a given name.
paul@199 175
paul@200 176
Attribute Locations
paul@200 177
-------------------
paul@200 178
paul@200 179
The locations stored in table/list elements are for instance attributes
paul@200 180
relative to the location of the instance, whereas those for class attributes
paul@200 181
and modules are absolute addresses (although these could also be changed to
paul@200 182
object-relative locations).
paul@200 183
paul@199 184
Objects and Structures 
paul@199 185
======================
paul@199 186
paul@199 187
As well as references, micropython needs to have actual objects to refer to.
paul@199 188
Since classes, functions and instances are all objects, it is desirable that
paul@199 189
certain common features and operations are supported in the same way for all
paul@199 190
of these things. To permit this, a common data structure format is used.
paul@199 191
paul@215 192
    Header....................................................  Attributes.................
paul@200 193
paul@215 194
    Identifier  Identifier  Address     Identifier  Size        Object      Object      ...
paul@199 195
paul@215 196
    0           1           2           3           4           5           6           7
paul@215 197
    classcode   attrcode/   invocation  funccode    size        __class__   attribute   ...
paul@215 198
                instance    reference                           reference   reference
paul@215 199
                status
paul@199 200
paul@206 201
Classcode
paul@206 202
---------
paul@206 203
paul@206 204
Used in attribute lookup.
paul@206 205
paul@199 206
Here, the classcode refers to the attribute lookup table for the object (as
paul@200 207
described above). Classes and instances share the same classcode, and their
paul@200 208
structures reflect this. Functions all belong to the same type and thus employ
paul@200 209
the classcode for the function built-in type, whereas modules have distinct
paul@200 210
types since they must support different sets of attributes.
paul@199 211
paul@206 212
Attrcode
paul@206 213
--------
paul@206 214
paul@206 215
Used to test instances for membership of classes (or descendants of classes).
paul@206 216
paul@206 217
Since, in traditional Python, classes are only ever instances of the "type"
paul@207 218
built-in class, support for testing such a relationship directly has been
paul@207 219
removed and the attrcode is not specified for classes: the presence of an
paul@207 220
attrcode indicates that a given object is an instance.
paul@206 221
paul@215 222
See the "Testing Instance Compatibility with Classes (Attrcode)" section below
paul@215 223
for details of attrcodes.
paul@214 224
paul@213 225
Invocation Reference
paul@213 226
--------------------
paul@213 227
paul@213 228
Used when an object is called.
paul@213 229
paul@213 230
This is the address of the code to be executed when an invocation is performed
paul@213 231
on the object.
paul@213 232
paul@215 233
Funccode
paul@215 234
--------
paul@213 235
paul@215 236
Used to look up argument positions by name.
paul@213 237
paul@215 238
The strategy with keyword arguments in micropython is to attempt to position
paul@215 239
such arguments in the invocation frame as it is being constructed.
paul@215 240
paul@215 241
See the "Parameters and Lookups" section for more information.
paul@215 242
paul@215 243
Size
paul@215 244
----
paul@215 245
paul@219 246
Used to indicate the size of an object including attributes.
paul@213 247
paul@209 248
Attributes
paul@209 249
----------
paul@209 250
paul@209 251
For classes, modules and instances, the attributes in the structure correspond
paul@209 252
to the attributes of each kind of object. For functions, however, the
paul@209 253
attributes in the structure correspond to the default arguments for each
paul@209 254
function, if any.
paul@209 255
paul@206 256
Structure Types
paul@206 257
---------------
paul@206 258
paul@199 259
Class C:
paul@199 260
paul@215 261
    0           1           2           3           4           5           6           7
paul@215 262
    classcode   (unused)    __new__     funccode    size        class type  attribute   ...
paul@215 263
    for C                   reference   for                     reference   reference
paul@215 264
                                        instantiator
paul@199 265
paul@199 266
Instance of C:
paul@199 267
paul@215 268
    0           1           2           3           4           5           6           7
paul@215 269
    classcode   attrcode    C.__call__  funccode    size        class C     attribute   ...
paul@215 270
    for C       for C       reference   for                     reference   reference
paul@215 271
                            (if exists) C.__call__
paul@199 272
paul@200 273
Function f:
paul@199 274
paul@215 275
    0           1           2           3           4           5           6           7
paul@215 276
    classcode   attrcode    code        funccode    size        class       attribute   ...
paul@215 277
    for         for         reference                           function    (default)
paul@215 278
    function    function                                        reference   reference
paul@200 279
paul@200 280
Module m:
paul@200 281
paul@215 282
    0           1           2           3           4           5           6           7
paul@219 283
    classcode   attrcode    (unused)    (unused)    (unused)    module type attribute   ...
paul@215 284
    for m       for m                                           reference   (global)
paul@215 285
                                                                            reference
paul@200 286
paul@200 287
The __class__ Attribute
paul@200 288
-----------------------
paul@200 289
paul@200 290
All objects support the __class__ attribute and this is illustrated above with
paul@200 291
the first attribute.
paul@200 292
paul@200 293
Class: refers to the type class (type.__class__ also refers to the type class)
paul@200 294
Function: refers to the function class
paul@200 295
Instance: refers to the class instantiated to make the object
paul@200 296
paul@203 297
Lists and Tuples
paul@203 298
----------------
paul@203 299
paul@203 300
The built-in list and tuple sequences employ variable length structures using
paul@203 301
the attribute locations to store their elements, where each element is a
paul@203 302
reference to a separately stored object.
paul@203 303
paul@214 304
Testing Instance Compatibility with Classes (Attrcode)
paul@200 305
------------------------------------------------------
paul@200 306
paul@200 307
Although it would be possible to have a data structure mapping classes to
paul@200 308
compatible classes, such as a matrix indicating the subclasses (or
paul@200 309
superclasses) of each class, the need to retain the key to such a data
paul@200 310
structure for each class might introduce a noticeable overhead.
paul@200 311
paul@200 312
Instead of having a separate structure, descendant classes of each class are
paul@200 313
inserted as special attributes into the object table. This requires an extra
paul@200 314
key to be retained, since each class must provide its own attribute code such
paul@200 315
that upon an instance/class compatibility test, the code may be obtained and
paul@200 316
used in the object table.
paul@200 317
paul@200 318
Invocation and Code References
paul@200 319
------------------------------
paul@200 320
paul@200 321
Modules: there is no meaningful invocation reference since modules cannot be
paul@200 322
explicitly called.
paul@200 323
paul@200 324
Functions: a simple code reference is employed pointing to code implementing
paul@200 325
the function. Note that the function locals are completely distinct from this
paul@200 326
structure and are not comparable to attributes. Instead, attributes are
paul@200 327
reserved for default parameter values, although they do not appear in the
paul@200 328
object table described above, appearing instead in a separate parameter table
paul@200 329
described below.
paul@200 330
paul@200 331
Classes: given that classes must be invoked in order to create instances, a
paul@200 332
reference must be provided in class structures. However, this reference does
paul@200 333
not point directly at the __init__ method of the class. Instead, the
paul@200 334
referenced code belongs to a special initialiser function, __new__, consisting
paul@200 335
of the following instructions:
paul@200 336
paul@200 337
    create instance for C
paul@200 338
    call C.__init__(instance, ...)
paul@200 339
    return instance
paul@200 340
paul@200 341
Instances: each instance employs a reference to any __call__ method defined in
paul@200 342
the class hierarchy for the instance, thus maintaining its callable nature.
paul@200 343
paul@200 344
Both classes and modules may contain code in their definitions - the former in
paul@200 345
the "body" of the class, potentially defining attributes, and the latter as
paul@200 346
the "top-level" code in the module, potentially defining attributes/globals -
paul@200 347
but this code is not associated with any invocation target. It is thus
paul@200 348
generated in order of appearance and is not referenced externally.
paul@200 349
paul@200 350
Invocation Operation
paul@200 351
--------------------
paul@200 352
paul@200 353
Consequently, regardless of the object an invocation is always done as
paul@200 354
follows:
paul@200 355
paul@200 356
    get invocation reference from the header
paul@200 357
    jump to reference
paul@200 358
paul@200 359
Additional preparation is necessary before the above code: positional
paul@200 360
arguments must be saved in the invocation frame, and keyword arguments must be
paul@200 361
resolved and saved to the appropriate position in the invocation frame.
paul@200 362
paul@200 363
See invocation.txt for details.
paul@200 364
paul@200 365
Parameters and Lookups 
paul@200 366
======================
paul@200 367
paul@200 368
Since Python supports keyword arguments when making invocations, it becomes
paul@200 369
necessary to record the parameter names associated with each function or
paul@200 370
method. Just as object tables record attributes positions on classes and
paul@200 371
instances, parameter tables record parameter positions in function or method
paul@200 372
parameter lists.
paul@200 373
paul@200 374
For a given program, a parameter table can be considered as being like a
paul@200 375
matrix mapping functions/methods to parameter names. For example:
paul@200 376
paul@200 377
    def f(x, y, z):
paul@200 378
        pass
paul@200 379
paul@200 380
    def g(a, b, c):
paul@200 381
        pass
paul@200 382
paul@200 383
    def h(a, x):
paul@200 384
        pass
paul@200 385
paul@200 386
This would provide the following table, referred to as a parameter table in
paul@200 387
the context of functions and methods:
paul@200 388
paul@200 389
    Function/param  a   b   c   x   y   z
paul@200 390
paul@200 391
    f                           1   2   3
paul@200 392
    g               1   2   3
paul@200 393
    h               1           2
paul@200 394
paul@200 395
Just as with parameter tables, a displacement list can be prepared from a
paul@200 396
parameter table:
paul@200 397
paul@200 398
                Functions with parameter (attribute) offsets
paul@200 399
paul@200 400
    funccode    f
paul@200 401
    attrcode    a   b   c   x   y   z
paul@200 402
paul@200 403
                                        g
paul@200 404
                                        a   b   c   x   y   z
paul@200 405
paul@200 406
                                                    h
paul@200 407
                                                    a   b   c   x   y   z
paul@200 408
paul@200 409
    List        .   .   .   1   2   3   1   2   3   1   .   .   2   .   .
paul@200 410
paul@200 411
Here, the funccode refers to the offset in the list at which a function's
paul@200 412
parameters are defined, whereas the attrcode defines the offset within a
paul@200 413
region of attributes corresponding to a single parameter of a given name.
paul@200 414
paul@200 415
Instantiation
paul@200 416
=============
paul@200 417
paul@200 418
When instantiating classes, memory must be reserved for the header of the
paul@200 419
resulting instance, along with locations for the attributes of the instance.
paul@200 420
Since the instance header contains data common to all instances of a class, a
paul@200 421
template header is copied to the start of the newly reserved memory region.