1 = Representing Program Objects = 2 3 Certain representations have been chosen for program objects that attempt to 4 support efficient access to those objects during the execution of a program. 5 6 <<TableOfContents(2,2)>> 7 8 == Attributes == 9 10 The principal means of referring to an object in a program is by using an 11 '''attribute''', having this name because it is the representation of an 12 attribute in classes, instances and modules. Each attribute can hold a 13 reference to an object, known as the '''value''', or other kinds of data: 14 15 {{{#!graphviz 16 //format=svg 17 //transform=notugly 18 digraph attributes { 19 node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Attributes"]; 20 edge [fontsize="13.0",fontname="Helvetica",tooltip="Attributes"]; 21 rankdir=TB; 22 23 attrA [label="attribute | { value |<value> reference to object }",shape=record]; 24 obj1 [label="<main> object | { attr1 | value } | { attr2 | value } | ...",shape=record]; 25 26 attrB [label="attribute | { intvalue |<intvalue> 12345 }",shape=record]; 27 28 attrA:value -> obj1:main; 29 } 30 }}} 31 32 Although a value indicates a specific object of interest for an attribute, if 33 the object is callable then additional '''context''' information may be 34 required to call the object. Such context information is not stored in an 35 attribute record but is instead obtained from the object itself, if 36 appropriate. 37 38 === Integer Representation === 39 40 The `intvalue` member of the attribute structure is employed instead of the 41 `value` member to store integer values. Since `value` normally holds a 42 pointer, and since pointers are often aligned to certain address boundaries on 43 many modern platforms (usually four-byte boundaries on 32-bit platforms, 44 eight-byte boundaries on 64-bit platforms, two-byte boundaries on platforms 45 with 16-bit addressing), the lowest significant bit (bit 0) will typically be 46 zero for a valid pointer. Consequently, by setting bit 0 to 1, other data can 47 be stored in the remaining bits and be distinguished from pointer information. 48 Obviously, operations on attributes first need to test whether the `value` 49 member or the `intvalue` member is in use by testing bit 0. 50 51 Thus, integers are transformed and stored directly within attributes, and they 52 are therefore passed around by value. When an attribute of an integer needs to 53 be accessed, the operation usually providing the `value` member, thus 54 obtaining an instance under normal circumstances, instead provides the address 55 of a common integer instance. This instance may then provide instance 56 attributes, whose values will be the same for all integers, or class 57 attributes through a reference to the integer (`int`) class. 58 59 Each method provided by `int`, when called, will be given the original 60 attribute for which the method was obtained as its context. In such methods, 61 operations on the context via `self` will either involve the propagation of 62 the attribute to other functions or methods or attribute accesses on `self`, 63 yielding common instance attributes or class attributes as already described. 64 Only native functions will attempt to interpret the attribute in a different 65 way, decoding the representation, performing arithmetic or logical operations, 66 and encoding the result in a new attribute. 67 68 == Contexts and Wrappers == 69 70 The context of an object is of significance if that object is callable. For 71 example, an instance may permit access to a method via an attribute. Since the 72 method will be callable, and since the method is accessed via the instance, 73 the context of that method will be the instance. In order to retain both 74 context and value information, a '''wrapper''' may be created. 75 76 {{{#!graphviz 77 //format=svg 78 //transform=notugly 79 digraph wrappers { 80 node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Wrappers"]; 81 edge [fontsize="13.0",fontname="Helvetica",tooltip="Wrappers"]; 82 rankdir=TB; 83 84 inst [label="<main> instance | { attr1 |<attr1> reference to method } | { attr2 | value } | ...",shape=record]; 85 method [label="<main> method | ...",shape=record]; 86 wrapper [label="<main> wrapper | { __context__ |<context> reference to instance } | { __value__ |<value> reference to method } | ...",shape=record]; 87 88 inst:attr1 -> method:main; 89 wrapper:context -> inst:main; 90 wrapper:value -> method:main; 91 } 92 }}} 93 94 The context is not always the accessor of the object - in this case, the 95 instance - because the object may already be a wrapper with its own context. 96 97 == Objects == 98 99 Classes, instances and modules are objects, and all of these kinds of objects 100 provide metadata describing the type of each object, together with a 101 collection of attributes forming the contents of such objects. 102 103 {{{#!graphviz 104 //format=svg 105 //transform=notugly 106 digraph objects { 107 node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Objects"]; 108 edge [fontsize="13.0",fontname="Helvetica",tooltip="Objects"]; 109 rankdir=TB; 110 111 instC [label="<main> instance of C | { 0 | reference to\ninstance table } | { __class__ |<cls> reference\nto C } | { a | value } | { b | value } | ...",shape=record]; 112 clsC [label="<main> class C | { class identifier | reference to\nclass table } | { __class__ |<cls> reference\nto type } | { __fn__ | instantiator\nreference } | { __args__ | reference to\nparameter table } | { f | <f> reference\nto f } | { g | value } | ...",shape=record]; 113 methodF [label="<main> function f | { 0 | reference to\ninstance table } | { __class__ |<cls> reference\nto function } | { __fn__ | method\nreference } | { __args__ | reference to\nparameter table } | ...",shape=record]; 114 function [label="<main> class function | { class identifier | reference to\nclass table } | { __class__ |<cls> reference\nto type } | ...",shape=record]; 115 type [label="<main> class type | { class identifier | reference to\nclass table } | { __class__ |<cls> reference\nto type } | ...",shape=record]; 116 117 instC:cls -> clsC:main; 118 clsC:cls -> type:main; 119 clsC:f -> methodF:main; 120 methodF:cls -> function:main; 121 } 122 }}} 123 124 Classes are represented by structures whose members reference class attributes 125 and class metadata (the class table), as well as incorporating invocation 126 metadata (the `__args__` and `__fn__` special attributes). 127 128 Instances are represented by structures whose members reference instance 129 attributes (including `__class__` which indicates the class instantiated by a 130 given instance) and instance metadata (the instance table), as well as 131 incorporating invocation metadata (the `__args__` and `__fn__` special 132 attributes). 133 134 Functions are instances of a general function type that does not permit 135 additional, general instance attributes. However, function instance structures 136 may have extra members corresponding to default parameter values. Access to 137 such extra members is performed using the minimum and maximum values provided 138 via `__args__` and with knowledge of the number of declared instance 139 attributes indicated by the instance table for the function type. 140 141 Modules are represented by structures whose members reference module 142 attributes and module metadata (the module table). 143 144 == Special Members == 145 146 All object representations support the following special members describing 147 the invocation properties of each object: 148 149 {{{#!table 150 `__args__` || the minimum number of arguments supported in an invocation and a 151 .. reference to the parameter table for the object 152 == 153 `__fn__` || a reference to a native function containing the actual code run 154 .. when calling the object 155 }}} 156 157 Classes are invoked in order to create instances of each class 158 ('''instantiation'''). Instances may support invocation by providing a 159 `__call__` method. Functions are supported by instances of a general function 160 class. Modules are generally not callable and will not actually provide these 161 special members in practice. 162 163 All object representations support information about their type: 164 165 {{{#!table 166 `__class__` 167 || the class of the object: instances refer to their classes, classes refer to 168 .. the `type` class, functions are instances that refer to the `function` 169 .. class, modules refer to the `module` class 170 }}} 171 172 Certain kinds of object support other descriptive attributes: 173 174 {{{#!table 175 `__name__` || the name of a class or a function 176 == 177 `__parent__` || the parent scope of a class or a function 178 }}} 179 180 Objects supported by native, system-level functionality require a means of 181 retaining information in special attributes: 182 183 {{{#!table 184 `__data__` || private data manipulated at the native level 185 }}} 186 187 Strings support special annotation attributes that permit their use in 188 dynamically resolving attributes: 189 190 {{{#!table 191 `__key__` || the code and position of the attribute whose name is represented 192 .. by the string 193 }}} 194 195 Such "key" attributes provide information that can be used to inspect an 196 object table and to test for the presence of an attribute. With such 197 information, the `getattr` and `hasattr` functions can be supported. 198 199 == Attribute Tables == 200 201 In order to provide information about the attributes supported by each object, 202 the structure of each object will reference a table containing entries 203 describing these supported attributes. The size of this table is declared 204 within the table structure, and for each position in the table an entry 205 corresponding to the same position within an actual object structure describes 206 the nature of the attribute at that position. 207 208 == Parameter Tables == 209 210 In order to support argument validation and keyword arguments in invocations, 211 a structure is referenced by `__args__` that indicates... 212 213 * The minimum number of parameters supported by a callable 214 * The maximum number of parameters supported by a callable 215 * The size of the table describing the parameters 216 * A table of entries with each entry indicating the nature of a parameter (in 217 effect, which name it uses, albeit as a generated code instead of a string) 218 and the position of the parameter in any argument list prepared for an 219 invocation 220 221 Parameter tables only need to be consulted at run-time if the nature of a 222 callable is undetermined. By supporting a uniform interface, the arguments 223 used in an invocation can be tested against the description provided by 224 `__args__` and the table.