Changes in / [be567e9:6d51bd7]


Ignore:
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • doc/proposals/vtable.md

    rbe567e9 r6d51bd7  
    11Proposal For Use of Virtual Tables
    22==================================
     3
     4This is an adaptation of the earlier virtual proposal, updating it with new
     5ideas, re-framing it and laying out more design decisions. It should
     6eventually replace the earlier proposal, but not all features and syntax have
     7been converted to the new design.
    38
    49The basic concept of a virtual table (vtable) is the same here as in most
     
    8893        }
    8994    }
    90 
    91 With a more complete widget trait you could, for example, construct a UI tool
    92 kit that can declare containers that hold widgets without knowing about the
    93 widget types. Making it reasonable to extend the tool kit.
    9495
    9596The trait types can also be used in the types of assertions on traits as well.
     
    243244We would also like to implement hierarchical relations between types.
    244245
    245     ast_node
    246     |-expression_node
    247     | |-operator_expression
    248     |
    249     |-statement_node
    250     | |-goto_statement
    251     |
    252     |-declaration_node
    253       |-using_declaration
    254       |-variable_declaration
     246    AstNode
     247    |-ParseNode
     248    | |-Declaration
     249    | | |-DeclarationWithType
     250    | | |-StructureDeclaration
     251    | |-Statement
     252    | | |-CompoundStatement
     253    | |-Expression
     254    |-Type
    255255
    256256Virtual tables by themselves are not quite enough to implement this system.
     
    315315    }
    316316
    317 This system does not support multiple inheritance. The system could be
    318 extended to support it or a limited form (ex. you may have multiple parents
    319 but they may not have a common ancestor). However this proposal focuses just
    320 on using hierachy as organization. Other uses for reusable/genaric code or
    321 shared interfaces is left for other features of the language.
    322 
    323317### Extension: Structural Inheritance
    324318An extension would be allow structures to be used as internal nodes on the
     
    360354solution but only works if we have exactly 1 vtable for each type. The second
    361355is to put a pointer to the type id in each vtable. This has more overhead but
    362 allows multiple vtables per type.
     356allows multiple vtables.
    363357
    364358    struct <trait>_vtable {
     
    373367        // Trait dependent list of vtable members.
    374368    };
    375 
    376 One important restriction is that only one instance of each typeid in memory.
    377 There is a ".gnu.linkonce" feature in the linker that might solve the issue.
    378369
    379370### Virtual Casts
     
    432423    io_error * error = (virtual)exc;
    433424
    434 #### Sample Implementation
    435 This cast implementation assumes a type id layout similar to the one given
    436 above. Also this code is definitely in the underlying C. Functions that give
    437 this functionality could exist in the standard library but these are meant to
    438 be produced by code translation of the virtual cast.
    439 
    440     bool is_in_subtree(typeid const * root, typeid const * id) {
    441         if (root == id) {
    442             return true
    443         } else if (NULL == id->parent) {
    444             return false;
    445         } else {
    446             return is_in_subtree(root, id->parent);
    447         }
    448     }
    449 
    450     void * virtual_cast(typeid const * target, void * value) {
    451         return is_in_subtree(target, *(typeid const **)value) ? value : NULL;
    452     }
    453 
    454 The virtual cast function might have to be wrapped with some casts to make it
    455 compile without warning.
    456 
    457 For the implicate target type we may be able to lean on the type resolution
    458 system that already exists. If the casting to ancestor type is built into
    459 the resolution then the impicate target could be decided by picking an
    460 overload, generated for each hierarchial type (here io_error and its root
    461 type exception).
    462 
    463     io_error * virtual_cast(exception * value) {
    464         return virtual_cast(io_error_typeid, value);
    465     }
    466 
    467425### Extension: Inline vtables
    468426Since the structures here are usually made to be turned into trait objects
     
    478436to allow access to all three options.
    479437
    480 The pointer to virtual table field on structures might implicately added (the
    481 types have to declare they are a child here) or created with a declaration,
    482 possibly like the one used to create the assertion.
    483 
    484438### Virtual Tables as Types
    485439Here we consider encoding plus the implementation of functions on it to be a
     
    488442and implementation.
    489443
    490 ### Question: Wrapping Structures
    491 One issue is what to do with concrete types at the base of the type tree.
    492 When we are working with the concrete type generally it would like them to be
    493 regular structures with direct calls. On the other hand for interactions with
    494 other types in the hierarchy it is more convenent for the type already to be
    495 cast.
    496 
    497 Which of these two should we use? Should we support both and if so how do we
    498 choose which one is being used at any given time.
    499 
    500 On a related note I have been using pointers two trait types here, as that
    501 is how many existing languages handle it. However the generic objects might
    502 be only one or two pointers wide passing the objects as a whole would not
    503 be very expensive and all operations on the generic objects probably have
    504 to be defined anyways.
    505 
    506444Resolution Scope
    507445----------------
     
    596534Stack allocated functions interact badly with this because they are not
    597535static. There are several ways to try to resolve this, however without a
    598 general solution most can keep vtables from making the existing thunk problem
    599 worse, they don't do anything to solve it.
     536general solution most can only buy time.
    600537
    601538Filling in some fields of a static vtable could cause issues on a recursive
     
    612549shortest lifetime of a function assigned to it. However this still limits the
    613550lifetime "implicitly" and returns to the original problem with thunks.
    614 
    615 Odds And Ends
    616 -------------
    617 
    618 In addition to the main design there are a few extras that should be
    619 considered. They are not part of the core design but make the new uses fully
    620 featured.
    621 
    622 ### Extension: Parent-Child Assertion
    623 For hierarchy types in regular traits, generic functions or generic structures
    624 we may want to be able to check parent-child relationships between two types
    625 given. For this we might have to add another primitive assertion. It would
    626 have the following form if declared in code:
    627 
    628     trait is_parent_child(dtype Parent, dtype Child) { <built-in magic> }
    629 
    630 This assertion is satified if Parent is an ancestor of Child in a hierarchy.
    631 In other words Child can be statically cast to Parent. The cast from Parent
    632 to child would be dynamically checked as usual.
    633 
    634 However in this form there are two concerns. The first that Parent will
    635 usually be consistent for a given use, it will not be a variable. Second is
    636 that we may also need the assertion functions. To do any casting/conversions
    637 anyways.
    638 TODO: Talk about when we wrap a concrete type and how that leads to "may".
    639 
    640 To this end it may be better that the parent trait combines the usual
    641 assertions plus this new primitive assertion. There may or may not be use
    642 cases for accessing just one half and providing easy access to them may be
    643 required depending on how that turns out.
    644 
    645     trait Parent(dtype T | interface(T)) virtual(<grand-parent?>) { }
    646 
    647 ### Extension: sizeof Compatablity
    648 Trait types are always sized, it may even be a fixed size like how pointers
    649 have the same size regardless of what they point at. However their contents
    650 may or may not be of a known size (if the `sized(...)` assertion is used).
    651 
    652 Currently there is no way to access this information. If it is needed a
    653 special syntax would have to be added. Here a special case of `sizeof` is
    654 used.
    655 
    656     struct line aLine;
    657     trait drawable widget = aLine;
    658 
    659     size_t x = sizeof(widget);
    660     size_t y = sizeof(trait drawable);
    661 
    662 As usual `y`, size of the type, is the size of the local storage used to put
    663 the value into. The other case `x` checks the saved stored value in the
    664 virtual table and returns that.
  • src/AST/Node.hpp

    rbe567e9 r6d51bd7  
    139139        operator const node_t * const() const { return node; }
    140140
    141         template<typename o_node_t>
    142         const o_node_t * as() const { return dynamic_cast<o_node_t *>(node); }
    143 
    144141        using ptr = const node_t *;
    145142
  • src/AST/porting.md

    rbe567e9 r6d51bd7  
    33## Pointer Types ##
    44* raw pointer `T*` is used for construction, but not storage
    5 * `ast::ptr_base<T,R>` is a pointer to AST node `T` with reference type `R`
    6   * specialization: strong pointer `ast::ptr<T>` is used for an ownership relationship
    7   * specialization: weak pointer `ast::readonly<T>` is used for an observation relationship
    8   * added `ast::ptr_base<T,R>::as<S>()` with same semantics as `dynamic_cast<S*>(p)`
     5* strong pointer `ast::ptr<T>` is used for an ownership relationship
     6* weak pointer `ast::readonly<T>` is used for an observation relationship
    97
    108## Visitors ##
     
    6260* Strong justification required for private fields
    6361  * No `get_` prefix on getters (including for generated fields)
    64     * exception is `DeclWithType::get_type()`
    6562* Notable changes:
    6663  * for concision and consistency with subclasses:
     
    115112* Still a `std::list` for children, rather than `std::vector`
    116113  * allows more-efficient splicing for purposes of later code generation
    117 
    118 `Type`
    119 * `forall` field split off into `ParameterizedType` subclass
    120   * any type that needs it can inherit from `ParameterizedType`
    121 * `get_qualifiers()` replaced with accessor `qualifiers()` and mutator `set_qualifiers()`
    122   * `get_CV()` replaced with `is_CV()` variants
    123 * A number of features only supported on aggregates pushed down to `ReferenceToType`:
    124   * `attributes`: per docs [1] GCC only supports type attributes on aggregates and typedefs
    125     * suggest adding a `TypeWithAttributes` wrapper type if this proves insufficient
    126   * `getAggr()`
    127   * `genericSubstitution()`
    128 
    129 `BasicType`
    130 * does not inherit from `Type` to allow pointer inlining
    131 * moved `Kind` before qualifiers in constructor to allow for default
    132 * **TODO** move `kind`, `typeNames` into code generator
    133 
    134 [1] https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Type-Attributes.html#Type-Attributes
    135 
Note: See TracChangeset for help on using the changeset viewer.