Changeset 50fb7df


Ignore:
Timestamp:
Sep 25, 2018, 2:17:18 PM (3 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer
Children:
560812b
Parents:
7428ad9
Message:

Updated the virtual proposal to cover the more dynamic approach.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/proposals/virtual.txt

    r7428ad9 r50fb7df  
    8787first polymorphic parameter).
    8888
    89 Once a function in a trait has been marked as virtual it defines a new
    90 function that takes in that trait's reference and then dynamically calls the
    91 underlying type implementation. Hence a trait reference becomes a kind of
    92 abstract type, cannot be directly instantiated but can still be used.
     89Instances of a trait are created by wrapping an existing instance of a type
     90that implements that trait. This wrapper includes all the function pointers
     91and other values required to preform the dynamic look-up. These are chosen by
     92the normal look-up rules at the point of abstraction.
    9393
    9494One of the limitations of this design is that it does not support double
     
    9898is also restricted, initially forbidden, see extension.
    9999
     100Ownership of the underlying structure is also a bit of a trick. Considering
     101the use cases for trait object, it is probably best to have the underlying
     102object be heap allocated and owned by the trait object.
     103
    100104Extension: Multi-parameter Virtual Traits:
    101105
     
    157161context, for instance if the cast occurs on the right hand side of an
    158162assignment.
     163
     164Function look-up follows the same rules as relaxed (behavioural) inheritance.
     165Traits can be upcast and down cast without losing information unless the
     166trait is cast down to a structure. Here there are two options.
     167
     168  Abstraction Time Binding: The more efficient and consistant with other parts
     169of CFA. Only the trait types use dynamic look-up, if converveted back into a
     170structure the normal static look-up rules find the function at compile time.
     171Casting down to a structure type can then result in the loss of a set of
     172bindings.
     173  Construction Time Binding: For more consistant handling of the virtual
     174structs, they are always considered wrapped. Functions are bound to the
     175instance the moment it is constructed and remain unchanged throughout its
     176lifetime, so down casting does not lose information.
     177
     178(We will have to decide between one of these two.)
    159179
    160180Extension: Multiple Parents
     
    205225
    206226We have so far been silent on how the vtable is created, stored and accessed.
    207 
    208 Creation happens at compile time. Function pointers are found by using the
    209 same best match rules as elsewhere (additional rules for defaults from the
    210 parent may or may not be required). For strict virtual this must happen at the
    211 global scope and forbidding static functions, to ensure that a single unique
    212 vtable is created. Similarly, there may have to be stricter matching rules
    213 for the functions that go into the vtable, possibly requiring an exact match.
    214 Relaxed virtual could relax both restrictions, if we allow different vtable
    215 at different conversion (struct to trait reference) sites. If it is allowed
    216 local functions being bound to a vtable could cause issues when they go out
    217 of scope, however this should follow the lifetime rules most C programs
    218 already follow implicitly.
    219 
    220 Most vtables should be stored statically, the only exception being some of
    221 the relaxed vtables that could have local function pointers. These may be able
    222 to be stack allocated. All vtables should be immutable and require no manual
    223 cleanup.
     227The vtables for the two types might be handled slightly differently and then
     228there is also the hierarchy data for virtual casts.
     229
     230The hierarchy data is simple conceptually. A single (exactly one copy) pointer
     231for each type can act as the identity for it. The value of the pointer is
     232its parent type, with the root pointer being NULL. Additional meta-data
     233can accompany the parent pointer, such as a string name or the vtable fields.
     234
     235They types of each vtable can be constructed from the definitions of the
     236traits (or internal nodes). The stand alone/base vtable is the same for both
     237kinds of inheritance. It may be argumented differently however (include parent
     238/this pointer in hierachal inheritance).
     239
     240Creation of the actual vtable is tricky. For classical single implementation
     241semantics we would assemble the functions and create one vtable at compile
     242time. However, not only does this not give CFA-like behaviour, it is
     243impossible generally because types can satify assertions in different ways at
     244different times and stop satifying them. A special set of harder rules could
     245be used, instead we have decided to try creating multiple vtables for each
     246type. The different vtables will all implement the same type but not always
     247in the same way.
     248
     249Storage has some issues from creation. If the contents of every vtable could
     250be determained at compile time they could all be created and stored
     251statically. However since thunks can be constructed on the stack and become
     252the best match, that isn't always possible. Those will have to be stored in
     253dynamic memory. Which means that all vtables must be stored dynamically or
     254there must be a way to determain which ones to free when the trait object is
     255destroyed.
    224256
    225257Access has two main options:
Note: See TracChangeset for help on using the changeset viewer.