# HG changeset patch # User Paul Boddie # Date 1238975860 -7200 # Node ID c78a7a57092d5cb8ff67daabe4b04b02f763ed4b # Parent a395698033f1d0ca5eca5685efb04d398017804b Split and renamed various tests. Moved parts of the documentation into a concepts document, adding some new material. Added an index document. diff -r a395698033f1 -r c78a7a57092d docs/concepts.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/concepts.txt Mon Apr 06 01:57:40 2009 +0200 @@ -0,0 +1,189 @@ +Concepts +======== + + * Contexts and values + * Tables and lookups + * Objects and structures + +Contexts and Values +=================== + +Values are used as the common reference representation in micropython: as +stored representations of attributes (of classes, instances, modules, and +other objects supporting attribute-like entities) as well as the stored values +associated with names in functions and methods. + +Unlike other implementations, micropython does not create things like bound +method objects for individual instances. Instead, all objects are referenced +using a context, reference pair: + +Value Layout +------------ + + 0 1 + context object + reference reference + +Specific implementations might reverse this ordering for optimisation +purposes. + +Rationale +--------- + +To reduce the number of created objects whilst retaining the ability to +support bound method invocations. The context indicates the context in which +an invocation is performed, typically the owner of the method. + +Usage +----- + +The context may be inserted as the first argument when a value is involved in +an invocation. This argument may then be omitted from the invocation if its +usage is not appropriate. + +See invocation.txt for details. + +Contexts in Acquired Values +--------------------------- + +There are two classes of instructions which provide values: + + Instruction Purpose Context Operations + ----------- ------- ------------------ + + LoadConst Load class, function, Combine null context with + module, constant loaded object + + LoadAddress Load attribute from Preserve or override stored + LoadAddressContext class, module, context (as described in + LoadAttr instance assignment.txt) + LoadAttrIndex + +In order to comply with traditional Python behaviour, contexts may or may not +represent the object from which an attribute has been acquired. + +See assignment.txt for details. + +Contexts in Stored Values +------------------------- + +There is only one class of instruction for storing values: + + Instruction Purpose Context Operations + ----------- ------- ------------------ + + StoreAddress Store attribute in a Preserve context; note that no + known object test for class attribute + assignment should be necessary + since this instruction should only + be generated for module globals + + StoreAttr Store attribute in an Preserve context; note that no + instance test for class attribute + assignment should be necessary + since this instruction should only + be generated for self accesses + + StoreAttrIndex Store attribute in an Preserve context; since the index + unknown object lookup could yield a class + attribute, a test of the nature of + the nature of the structure is + necessary in order to prevent + assignments to classes + +Note that contexts are never changed in the stored value: they are preserved. + +See assignment.txt for details. + +Tables and Lookups +================== + +Attribute lookups, where the exact location of an object attribute is deduced, +are performed differently in micropython than in other implementations. +Instead of providing attribute dictionaries, in which attributes are found, +attributes are located at fixed places in object structures (described below) +and their locations are stored using a special representation known as a +table. + +For a given program, a table can be considered as being like a matrix mapping +classes to attribute names. For example: + + class A: + # has attributes x, y + + class B(A): + # introduces attribute z + + class C: + # has attributes a, b, z + +This would provide the following table: + + Class/attr a b x y z + + A 1 2 + B 1 2 3 + C 1 2 3 + +A limitation of this representation is that instance attributes may not shadow +class attributes: if an attribute with a given name is not defined on an +instance, an attribute with the same name cannot be provided by the class of +the instance or any superclass of the instance's class. + +The table can be compacted using a representation known as a displacement +list: + + Classes with attribute offsets + + classcode A + attrcode a b x y z + + B + a b x y z + + C + a b x y z + + List . . 1 2 1 2 3 1 2 . . 3 + +Here, the classcode refers to the offset in the list at which a class's +attributes are defined, whereas the attrcode defines the offset within a +region of attributes corresponding to a single attribute of a given name. + +Objects and Structures +====================== + +As well as references, micropython needs to have actual objects to refer to. +Since classes, functions and instances are all objects, it is desirable that +certain common features and operations are supported in the same way for all +of these things. To permit this, a common data structure format is used. + + Identifier Identifier Address Details Type Object ... + + 0 1 2 3 4 5 6 + classcode attrcode invocation invocation __class__ attribute ... + reference #args, reference reference + defaults + reference + +Here, the classcode refers to the attribute lookup table for the object (as +described above). Since classes and instances share the same classcode, they +might resemble the following: + +Class C: + + 0 1 2 3 4 5 6 + code for C attrcode __new__ __new__ class type attribute ... + for C reference #args, reference reference + defaults + reference + +Instance of C: + + 0 1 2 3 4 5 6 + code for C attrcode C.__call__ C.__call__ class C attribute ... + for C reference #args, reference reference + (if exists) defaults + reference + + diff -r a395698033f1 -r c78a7a57092d docs/index.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/index.txt Mon Apr 06 01:57:40 2009 +0200 @@ -0,0 +1,4 @@ +Documentation Index +=================== + +concepts.txt diff -r a395698033f1 -r c78a7a57092d docs/structures.txt --- a/docs/structures.txt Sun Apr 05 17:15:59 2009 +0200 +++ b/docs/structures.txt Mon Apr 06 01:57:40 2009 +0200 @@ -1,79 +1,6 @@ Data Structures =============== -The fundamental "value type" is a pair of references: one pointing to the -referenced object represented by the interchangeable value; one referring to -the context of the referenced object, typically the object through which the -referenced object was acquired as an attribute. - -Value Layout ------------- - - 0 1 - object context - reference reference - -Such values are used as the stored representations of attributes (of classes, -instances, modules, and other objects supporting attribute-like entities) as -well as the stored values associated with names in functions and methods. - -Stored Values and Contexts --------------------------- - -See assignment.txt for information about contexts and transformations. - -Acquiring Values ----------------- - -There are two classes of instructions which provide values: - - Instruction Purpose Context Operations - ----------- ------- ------------------ - - LoadConst Load class, function, Combine null context with - module, constant loaded object - - LoadAddress Load attribute from Preserve or override stored - LoadAddressContext class, module, context (as described in - LoadAttr instance assignment.txt) - LoadAttrIndex - -Storing Values --------------- - -There is only one class of instruction for storing values: - - Instruction Purpose Context Operations - ----------- ------- ------------------ - - StoreAddress Store attribute in a Preserve context; note that no - known object test for class attribute - assignment should be necessary - since this instruction should only - be generated for module globals - - StoreAttr Store attribute in an Preserve context; note that no - instance test for class attribute - assignment should be necessary - since this instruction should only - be generated for self accesses - - StoreAttrIndex Store attribute in an Preserve context; since the index - unknown object lookup could yield a class - attribute, a test of the nature of - the nature of the structure is - necessary in order to prevent - assignments to classes - -Note that contexts are never changed in the stored value: they are preserved. -See assignment.txt for more information. - -Objects -------- - -Since classes, functions and instances are all "objects", each must support -certain features and operations in the same way. - The __class__ Attribute ----------------------- @@ -95,36 +22,6 @@ Structure Layout ---------------- -A suitable structure layout might be something like this: - - Identifier Identifier Address Details Type Object ... - - 0 1 2 3 4 5 6 - classcode attrcode invocation invocation __class__ attribute ... - reference #args, reference reference - defaults - reference - -Here, the classcode refers to the attribute lookup table for the object. Since -classes and instances share the same classcode, they might resemble the -following: - -Class C: - - 0 1 2 3 4 5 6 - code for C attrcode __new__ __new__ class type attribute ... - for C reference #args, reference reference - defaults - reference - -Instance of C: - - 0 1 2 3 4 5 6 - code for C attrcode C.__call__ C.__call__ class C attribute ... - for C reference #args, reference reference - (if exists) defaults - reference - The __new__ reference would lead to code consisting of the following instructions: diff -r a395698033f1 -r c78a7a57092d tests/call_func.py --- a/tests/call_func.py Sun Apr 05 17:15:59 2009 +0200 +++ b/tests/call_func.py Mon Apr 06 01:57:40 2009 +0200 @@ -7,12 +7,4 @@ f(1, b=2, c=3) f(c=3, b=2, a=1) -g = f -g(1, c=3, b=2) - -def g(a, c, b): - pass - -g(1, c=3, b=2) - # vim: tabstop=4 expandtab shiftwidth=4 diff -r a395698033f1 -r c78a7a57092d tests/call_func_uncertain.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/call_func_uncertain.py Mon Apr 06 01:57:40 2009 +0200 @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +def f(a, b, c): + pass + +g = f +g(1, c=3, b=2) + +def g(a, c, b): + pass + +g(1, c=3, b=2) + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r a395698033f1 -r c78a7a57092d tests/call_instance.py --- a/tests/call_instance.py Sun Apr 05 17:15:59 2009 +0200 +++ b/tests/call_instance.py Mon Apr 06 01:57:40 2009 +0200 @@ -5,6 +5,6 @@ return "called" c = C() -c() +result = c() # vim: tabstop=4 expandtab shiftwidth=4 diff -r a395698033f1 -r c78a7a57092d tests/call_instance2.py --- a/tests/call_instance2.py Sun Apr 05 17:15:59 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -#!/usr/bin/env python - -class C: - def __call__(self): - return "called" - -class D: - def __init__(self, x): - self.x = x - -c = C() -d = D(c) -d.x() - -# vim: tabstop=4 expandtab shiftwidth=4 diff -r a395698033f1 -r c78a7a57092d tests/call_instance_attribute.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/call_instance_attribute.py Mon Apr 06 01:57:40 2009 +0200 @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +class C: + def __call__(self): + return "called" + +class D: + def __init__(self, x): + self.x = x + +c = C() +d = D(c) +result = d.x() + +# vim: tabstop=4 expandtab shiftwidth=4