|
| 1 | +# REPR Compose Protocol |
| 2 | + |
| 3 | +In 6model, representations take responsibility for memory layout, while a |
| 4 | +meta-object is responsible for other aspects of type-ness (dispatch, type |
| 5 | +checking, etc.) Typically, meta-objects are at some point "composed" - that |
| 6 | +is, they reach a point where the definition of the type they represent is |
| 7 | +either closed or complete in some sense. Certain representations need to be |
| 8 | +(or in some cases, may be) configured. For example, a representation that does |
| 9 | +efficient storage of an object's attributes needs configuring with information |
| 10 | +about the things it should store. This configuration happens through the REPR |
| 11 | +composition protocol. The meta-object uses the nqp::composetype primitive in |
| 12 | +order to do this. |
| 13 | + |
| 14 | +The protocol is defined entirely in terms of arrays and hashes. Why? So we |
| 15 | +don't have to define a particularly complex object system in order to define |
| 16 | +an object system. :-) At the top level, a hash is always passed. Its keys |
| 17 | +indicate the configuration for a specific part of the protocol, the the values |
| 18 | +are a data structure providing the appropriate information. |
| 19 | + |
| 20 | +The rest of this documentation describes these protocols; each heading is a |
| 21 | +key that can appear in the top level hash, and what's below it indicates what |
| 22 | +should fall beneath those keys. |
| 23 | + |
| 24 | +## attribute |
| 25 | + |
| 26 | +The value is an array with one element for each entry in the MRO, from most |
| 27 | +derived to least derived. Each element is in turn an array, consisting of 3 |
| 28 | +elements: |
| 29 | + |
| 30 | +* The type object of the type at this point in the MRO |
| 31 | +* An array of hashes, each hash describing an attribute |
| 32 | +* The immediate parents, if any, of the type object in question |
| 33 | + |
| 34 | +The hash describing an individual attribute must have the following keys: |
| 35 | + |
| 36 | +* name - provides the name of the attribute |
| 37 | + |
| 38 | +It may optionally have these keys: |
| 39 | + |
| 40 | +* type - type object specifying the type of the attribute. Note that this is |
| 41 | + used purely for the purpose of allocation. It is NOT up to the REPR to do |
| 42 | + type checks. Anything without this is assumed to be a reference type. In |
| 43 | + fact, anything that's a reference type is uninteresting in terms of this |
| 44 | + key since it just gets a reference to another object. It's native types or |
| 45 | + other compact things that can be flattened into the object body that are |
| 46 | + interesting. |
| 47 | + |
| 48 | +* box_target - if this key is present, then this type is a target for boxing |
| 49 | + or unboxing. |
| 50 | + |
| 51 | +* auto_viv_container - if this key is present then an access to an attribute |
| 52 | + that is uninitialized will cause that attribute to be set to a clone of the |
| 53 | + value under this key. If the value is a type object, the clone will not take |
| 54 | + place, since cloning a type object is meaningless. |
| 55 | + |
| 56 | +* positional_delegate - if this key is present, the given (reference type) |
| 57 | + attribute will be delegated to if the positional part of the REPR API is |
| 58 | + used with the object. This is primarily to support languages that need to |
| 59 | + reasonably efficiently provide positional things that can also be mixed |
| 60 | + in to in arbitrary ways. |
| 61 | + |
| 62 | +* associative_delegate - the same as positional_delegate, for the associative |
| 63 | + part of the REPR API. |
| 64 | + |
| 65 | +## integer |
| 66 | + |
| 67 | +A hash that may have the following keys: |
| 68 | + |
| 69 | +* bits - the number of bits. Which sizes are supported are up to the REPR. |
| 70 | + |
| 71 | +* unsigned - if this key exists, then the stored value is unsigned. |
| 72 | + |
| 73 | +## float |
| 74 | + |
| 75 | +A hash that may have the following keys: |
| 76 | + |
| 77 | +* bits - the number of bits. Which sizes are supported are up to the REPR. |
| 78 | + |
| 79 | +## array |
| 80 | + |
| 81 | +A hash that may have the following keys: |
| 82 | + |
| 83 | +* type - the type of the array attributes. While all reference types are |
| 84 | + equivalent, native types will be inlined, leading to a compact array. A REPR |
| 85 | + is free to decide what types it supports, and just because it is asked to be |
| 86 | + an array of 1-bit ints in no way obligates it to use a bit of storage for |
| 87 | + each element. Again, this is just about layout and lookup, not about type |
| 88 | + checking. |
| 89 | + |
| 90 | +## hash |
| 91 | + |
| 92 | +* valuetype - the type of the hash value. As with arrays, it's up to the REPR |
| 93 | + how or if it handles native types. Just about layout. |
| 94 | + |
| 95 | +* keytype - the type of the hash key. REPRs are likely to be restrictive here, |
| 96 | + since they need to understand the representation of the provided key well |
| 97 | + enough to hash it. This will probably mean strings and whatever REPR ObjAt |
| 98 | + in Perl 6 (or some other language's variant) has. |
0 commit comments