micropython

Annotated docs/evaluation.txt

470:138fa7678c43
2011-09-12 Paul Boddie Filtered out unused classes from the descendants stored for each class in the object table. Especially for the 'object' class, this makes it possible to reduce the table substantially.
paul@153 1
Instruction Evaluation Model
paul@153 2
============================
paul@153 3
paul@153 4
Programs use a value stack containing local and temporary storage. A value
paul@153 5
stack pointer indicates the top of this stack. In addition, a separate stack
paul@153 6
is used to record the invocation frames. All stack pointers refer to the next
paul@153 7
address to be used by the stack, not the address of the uppermost element.
paul@153 8
paul@153 9
    Frame Stack     Value Stack
paul@153 10
    -----------     -----------     Address of Callable
paul@153 11
                                    -------------------
paul@153 12
    previous        ...
paul@153 13
    current ------> callable -----> identifier
paul@153 14
                    arg1            reference to code
paul@153 15
                    arg2
paul@153 16
                    arg3
paul@153 17
                    local4
paul@153 18
                    local5
paul@153 19
                    ...
paul@153 20
paul@153 21
Unlike the CPython virtual machine, programs do not use a value stack
paul@153 22
containing the results of expression evaluations. Instead, temporary storage
paul@153 23
is statically allocated and employed by instructions.
paul@153 24
paul@153 25
Loading local names and temporary values is a matter of performing
paul@153 26
frame-relative accesses to the value stack.
paul@153 27
paul@153 28
Invocations and Argument Evaluation
paul@153 29
-----------------------------------
paul@153 30
paul@153 31
When preparing for an invocation, the caller first sets the invocation frame
paul@153 32
pointer. A number of locations for the arguments required by the invocation
paul@153 33
are then reserved. With a frame to prepare, positional arguments are added to
paul@153 34
the frame in order such that the first argument positions are filled. The
paul@153 35
names of keyword arguments are used (in the form of table index values) to
paul@153 36
consult the parameter table and to find the frame location in which such
paul@153 37
arguments are to be stored.
paul@153 38
paul@153 39
    fn(a, b, d=1, e=2, c=3) -> fn(a, b, c, d, e)
paul@153 40
paul@153 41
    Frame
paul@153 42
    -----
paul@153 43
paul@153 44
    a               a               a               a
paul@153 45
    b               b               b               b
paul@153 46
    ___             ___             ___         --> 3
paul@153 47
    ___         --> 1               1           |   1
paul@153 48
    ___         |   ___         --> 2           |   2
paul@201 49
                |               |               |
paul@153 50
    1 -----------   2 -----------   3 -----------
paul@153 51
paul@153 52
Conceptually, the frame can be considered as a collection of attributes, as
paul@153 53
seen in other kinds of structures:
paul@153 54
paul@153 55
Frame for invocation of fn:
paul@153 56
paul@153 57
    0           1           2           3           4           5
paul@153 58
    code        a           b           c           d           e
paul@153 59
    reference
paul@153 60
paul@153 61
However, where arguments are specified positionally, such "attributes" are not
paul@153 62
set using a comparable approach to that employed with other structures.
paul@153 63
Keyword arguments are set using an attribute-like mechanism, though, where the
paul@153 64
position of each argument discovered using the parameter table.
paul@153 65
paul@153 66
Method Invocations
paul@153 67
------------------
paul@153 68
paul@153 69
Method invocations incorporate an implicit first argument which is obtained
paul@153 70
from the context of the method:
paul@153 71
paul@153 72
    method(a, b, d=1, e=2, c=3) -> method(self, a, b, c, d, e)
paul@153 73
paul@153 74
    Frame
paul@153 75
    -----
paul@153 76
paul@153 77
    context of method
paul@153 78
    a
paul@153 79
    b
paul@153 80
    3
paul@153 81
    1
paul@153 82
    2
paul@153 83
paul@153 84
Although it could be possible to permit any object to be provided as the first
paul@153 85
argument, in order to optimise instance attribute access in methods, we should
paul@153 86
seek to restrict the object type.
paul@153 87
paul@153 88
Verifying Supplied Arguments
paul@153 89
----------------------------
paul@153 90
paul@153 91
In order to ensure a correct invocation, it is also necessary to check the
paul@153 92
number of supplied arguments. If the target of the invocation is known at
paul@153 93
compile-time, no additional instructions need to be emitted; otherwise, the
paul@153 94
generated code must test for the following situations:
paul@153 95
paul@153 96
 1. That the number of supplied arguments is equal to the number of expected
paul@153 97
    parameters.
paul@153 98
paul@153 99
 2. That no keyword argument overwrites an existing positional parameter.
paul@153 100
paul@153 101
Default Arguments
paul@153 102
-----------------
paul@153 103
paul@153 104
Some arguments may have default values which are used if no value is provided
paul@153 105
in an invocation. Such defaults are initialised when the function itself is
paul@153 106
initialised, and are used to fill in any invocation frames that are known at
paul@153 107
compile-time.
paul@153 108
paul@153 109
Tuples, Frames and Allocation
paul@153 110
-----------------------------
paul@153 111
paul@153 112
Using the approach where arguments are treated like attributes in some kind of
paul@153 113
structure, we could choose to allocate frames in places other than a stack.
paul@153 114
This would produce something somewhat similar to a plain tuple object.