Changeset 881f590


Ignore:
Timestamp:
May 14, 2019, 12:02:48 PM (5 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
62315a0
Parents:
9b81fed3
Message:

Moved anything I felt was worth saving from virtual to vtable. Cleared out virtual.txt.

Location:
doc/proposals
Files:
1 deleted
1 edited

Legend:

Unmodified
Added
Removed
  • doc/proposals/vtable.md

    r9b81fed3 r881f590  
    9393        }
    9494    }
     95
     96With a more complete widget trait you could, for example, construct a UI tool
     97kit that can declare containers that hold widgets without knowing about the
     98widget types. Making it reasonable to extend the tool kit.
    9599
    96100The trait types can also be used in the types of assertions on traits as well.
     
    244248We would also like to implement hierarchical relations between types.
    245249
    246     AstNode
    247     |-ParseNode
    248     | |-Declaration
    249     | | |-DeclarationWithType
    250     | | |-StructureDeclaration
    251     | |-Statement
    252     | | |-CompoundStatement
    253     | |-Expression
    254     |-Type
     250    ast_node
     251    |-expression_node
     252    | |-operator_expression
     253    |
     254    |-statement_node
     255    | |-goto_statement
     256    |
     257    |-declaration_node
     258      |-using_declaration
     259      |-variable_declaration
    255260
    256261Virtual tables by themselves are not quite enough to implement this system.
     
    315320    }
    316321
     322This system does not support multiple inheritance. The system could be
     323extended to support it or a limited form (ex. you may have multiple parents
     324but they may not have a common ancestor). However this proposal focuses just
     325on using hierachy as organization. Other uses for reusable/genaric code or
     326shared interfaces is left for other features of the language.
     327
    317328### Extension: Structural Inheritance
    318329An extension would be allow structures to be used as internal nodes on the
     
    354365solution but only works if we have exactly 1 vtable for each type. The second
    355366is to put a pointer to the type id in each vtable. This has more overhead but
    356 allows multiple vtables.
     367allows multiple vtables per type.
    357368
    358369    struct <trait>_vtable {
     
    367378        // Trait dependent list of vtable members.
    368379    };
     380
     381One important restriction is that only one instance of each typeid in memory.
     382There is a ".gnu.linkonce" feature in the linker that might solve the issue.
    369383
    370384### Virtual Casts
     
    423437    io_error * error = (virtual)exc;
    424438
     439#### Sample Implementation
     440This cast implementation assumes a type id layout similar to the one given
     441above. Also this code is definitely in the underlying C. Functions that give
     442this functionality could exist in the standard library but these are meant to
     443be produced by code translation of the virtual cast.
     444
     445    bool is_in_subtree(typeid const * root, typeid const * id) {
     446        if (root == id) {
     447            return true
     448        } else if (NULL == id->parent) {
     449            return false;
     450        } else {
     451            return is_in_subtree(root, id->parent);
     452        }
     453    }
     454
     455    void * virtual_cast(typeid const * target, void * value) {
     456        return is_in_subtree(target, *(typeid const **)value) ? value : NULL;
     457    }
     458
     459The virtual cast function might have to be wrapped with some casts to make it
     460compile without warning.
     461
     462For the implicate target type we may be able to lean on the type resolution
     463system that already exists. If the casting to ancestor type is built into
     464the resolution then the impicate target could be decided by picking an
     465overload, generated for each hierarchial type (here io_error and its root
     466type exception).
     467
     468    io_error * virtual_cast(exception * value) {
     469        return virtual_cast(io_error_typeid, value);
     470    }
     471
    425472### Extension: Inline vtables
    426473Since the structures here are usually made to be turned into trait objects
     
    436483to allow access to all three options.
    437484
     485The pointer to virtual table field on structures might implicately added (the
     486types have to declare they are a child here) or created with a declaration,
     487possibly like the one used to create the assertion.
     488
    438489### Virtual Tables as Types
    439490Here we consider encoding plus the implementation of functions on it to be a
     
    442493and implementation.
    443494
     495### Question: Wrapping Structures
     496One issue is what to do with concrete types at the base of the type tree.
     497When we are working with the concrete type generally it would like them to be
     498regular structures with direct calls. On the other hand for interactions with
     499other types in the hierarchy it is more convenent for the type already to be
     500cast.
     501
     502Which of these two should we use? Should we support both and if so how do we
     503choose which one is being used at any given time.
     504
     505On a related note I have been using pointers two trait types here, as that
     506is how many existing languages handle it. However the generic objects might
     507be only one or two pointers wide passing the objects as a whole would not
     508be very expensive and all operations on the generic objects probably have
     509to be defined anyways.
     510
    444511Resolution Scope
    445512----------------
     
    534601Stack allocated functions interact badly with this because they are not
    535602static. There are several ways to try to resolve this, however without a
    536 general solution most can only buy time.
     603general solution most can keep vtables from making the existing thunk problem
     604worse, they don't do anything to solve it.
    537605
    538606Filling in some fields of a static vtable could cause issues on a recursive
     
    549617shortest lifetime of a function assigned to it. However this still limits the
    550618lifetime "implicitly" and returns to the original problem with thunks.
     619
     620Odds And Ends
     621-------------
     622
     623In addition to the main design there are a few extras that should be
     624considered. They are not part of the core design but make the new uses fully
     625featured.
     626
     627### Extension: Parent-Child Assertion
     628For hierarchy types in regular traits, generic functions or generic structures
     629we may want to be able to check parent-child relationships between two types
     630given. For this we might have to add another primitive assertion. It would
     631have the following form if declared in code:
     632
     633    trait is_parent_child(dtype Parent, dtype Child) { <built-in magic> }
     634
     635This assertion is satified if Parent is an ancestor of Child in a hierarchy.
     636In other words Child can be statically cast to Parent. The cast from Parent
     637to child would be dynamically checked as usual.
     638
     639However in this form there are two concerns. The first that Parent will
     640usually be consistent for a given use, it will not be a variable. Second is
     641that we may also need the assertion functions. To do any casting/conversions
     642anyways.
     643TODO: Talk about when we wrap a concrete type and how that leads to "may".
     644
     645To this end it may be better that the parent trait combines the usual
     646assertions plus this new primitive assertion. There may or may not be use
     647cases for accessing just one half and providing easy access to them may be
     648required depending on how that turns out.
     649
     650    trait Parent(dtype T | interface(T)) virtual(<grand-parent?>) { }
     651
     652### Extension: sizeof Compatablity
     653Trait types are always sized, it may even be a fixed size like how pointers
     654have the same size regardless of what they point at. However their contents
     655may or may not be of a known size (if the `sized(...)` assertion is used).
     656
     657Currently there is no way to access this information. If it is needed a
     658special syntax would have to be added. Here a special case of `sizeof` is
     659used.
     660
     661    struct line aLine;
     662    trait drawable widget = aLine;
     663
     664    size_t x = sizeof(widget);
     665    size_t y = sizeof(trait drawable);
     666
     667As usual `y`, size of the type, is the size of the local storage used to put
     668the value into. The other case `x` checks the saved stored value in the
     669virtual table and returns that.
Note: See TracChangeset for help on using the changeset viewer.