Changeset 881f590
- Timestamp:
- May 14, 2019, 12:02:48 PM (6 years ago)
- 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
- Location:
- doc/proposals
- Files:
-
- 1 deleted
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/proposals/vtable.md
r9b81fed3 r881f590 93 93 } 94 94 } 95 96 With a more complete widget trait you could, for example, construct a UI tool 97 kit that can declare containers that hold widgets without knowing about the 98 widget types. Making it reasonable to extend the tool kit. 95 99 96 100 The trait types can also be used in the types of assertions on traits as well. … … 244 248 We would also like to implement hierarchical relations between types. 245 249 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 255 260 256 261 Virtual tables by themselves are not quite enough to implement this system. … … 315 320 } 316 321 322 This system does not support multiple inheritance. The system could be 323 extended to support it or a limited form (ex. you may have multiple parents 324 but they may not have a common ancestor). However this proposal focuses just 325 on using hierachy as organization. Other uses for reusable/genaric code or 326 shared interfaces is left for other features of the language. 327 317 328 ### Extension: Structural Inheritance 318 329 An extension would be allow structures to be used as internal nodes on the … … 354 365 solution but only works if we have exactly 1 vtable for each type. The second 355 366 is to put a pointer to the type id in each vtable. This has more overhead but 356 allows multiple vtables .367 allows multiple vtables per type. 357 368 358 369 struct <trait>_vtable { … … 367 378 // Trait dependent list of vtable members. 368 379 }; 380 381 One important restriction is that only one instance of each typeid in memory. 382 There is a ".gnu.linkonce" feature in the linker that might solve the issue. 369 383 370 384 ### Virtual Casts … … 423 437 io_error * error = (virtual)exc; 424 438 439 #### Sample Implementation 440 This cast implementation assumes a type id layout similar to the one given 441 above. Also this code is definitely in the underlying C. Functions that give 442 this functionality could exist in the standard library but these are meant to 443 be 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 459 The virtual cast function might have to be wrapped with some casts to make it 460 compile without warning. 461 462 For the implicate target type we may be able to lean on the type resolution 463 system that already exists. If the casting to ancestor type is built into 464 the resolution then the impicate target could be decided by picking an 465 overload, generated for each hierarchial type (here io_error and its root 466 type exception). 467 468 io_error * virtual_cast(exception * value) { 469 return virtual_cast(io_error_typeid, value); 470 } 471 425 472 ### Extension: Inline vtables 426 473 Since the structures here are usually made to be turned into trait objects … … 436 483 to allow access to all three options. 437 484 485 The pointer to virtual table field on structures might implicately added (the 486 types have to declare they are a child here) or created with a declaration, 487 possibly like the one used to create the assertion. 488 438 489 ### Virtual Tables as Types 439 490 Here we consider encoding plus the implementation of functions on it to be a … … 442 493 and implementation. 443 494 495 ### Question: Wrapping Structures 496 One issue is what to do with concrete types at the base of the type tree. 497 When we are working with the concrete type generally it would like them to be 498 regular structures with direct calls. On the other hand for interactions with 499 other types in the hierarchy it is more convenent for the type already to be 500 cast. 501 502 Which of these two should we use? Should we support both and if so how do we 503 choose which one is being used at any given time. 504 505 On a related note I have been using pointers two trait types here, as that 506 is how many existing languages handle it. However the generic objects might 507 be only one or two pointers wide passing the objects as a whole would not 508 be very expensive and all operations on the generic objects probably have 509 to be defined anyways. 510 444 511 Resolution Scope 445 512 ---------------- … … 534 601 Stack allocated functions interact badly with this because they are not 535 602 static. There are several ways to try to resolve this, however without a 536 general solution most can only buy time. 603 general solution most can keep vtables from making the existing thunk problem 604 worse, they don't do anything to solve it. 537 605 538 606 Filling in some fields of a static vtable could cause issues on a recursive … … 549 617 shortest lifetime of a function assigned to it. However this still limits the 550 618 lifetime "implicitly" and returns to the original problem with thunks. 619 620 Odds And Ends 621 ------------- 622 623 In addition to the main design there are a few extras that should be 624 considered. They are not part of the core design but make the new uses fully 625 featured. 626 627 ### Extension: Parent-Child Assertion 628 For hierarchy types in regular traits, generic functions or generic structures 629 we may want to be able to check parent-child relationships between two types 630 given. For this we might have to add another primitive assertion. It would 631 have the following form if declared in code: 632 633 trait is_parent_child(dtype Parent, dtype Child) { <built-in magic> } 634 635 This assertion is satified if Parent is an ancestor of Child in a hierarchy. 636 In other words Child can be statically cast to Parent. The cast from Parent 637 to child would be dynamically checked as usual. 638 639 However in this form there are two concerns. The first that Parent will 640 usually be consistent for a given use, it will not be a variable. Second is 641 that we may also need the assertion functions. To do any casting/conversions 642 anyways. 643 TODO: Talk about when we wrap a concrete type and how that leads to "may". 644 645 To this end it may be better that the parent trait combines the usual 646 assertions plus this new primitive assertion. There may or may not be use 647 cases for accessing just one half and providing easy access to them may be 648 required depending on how that turns out. 649 650 trait Parent(dtype T | interface(T)) virtual(<grand-parent?>) { } 651 652 ### Extension: sizeof Compatablity 653 Trait types are always sized, it may even be a fixed size like how pointers 654 have the same size regardless of what they point at. However their contents 655 may or may not be of a known size (if the `sized(...)` assertion is used). 656 657 Currently there is no way to access this information. If it is needed a 658 special syntax would have to be added. Here a special case of `sizeof` is 659 used. 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 667 As usual `y`, size of the type, is the size of the local storage used to put 668 the value into. The other case `x` checks the saved stored value in the 669 virtual table and returns that.
Note: See TracChangeset
for help on using the changeset viewer.