source: libcfa/src/virtual_dtor.hfa @ 2c38b15

Last change on this file since 2c38b15 was 1e940de0, checked in by caparsons <caparson@…>, 17 months ago

cleanup/bugfix actors and fix virtual dtor bug

  • Property mode set to 100644
File size: 2.0 KB
Line 
1// inline this structure to have a virtual dtor.
2// when using this, delete() is also virtual and will be called on the right address
3// using free() directly on polymorphic types may result in unaligned memory deallocation
4//     in multi-inheritance or in single inheritance if the inline isn't the first field
5
6// This supports virtual dtors for both single and multiple inheritance,
7// however it does not support multiple inheritance of the virtual_dtor. e.g.:
8//     given struct A { inline virtual_dtor; } and struct B { inline virtual_dtor; }
9//     struct C { inline A; inline B; } will result in undefined behaviour
10
11struct virtual_dtor {
12    void (*__virtual_dtor_ptr)(virtual_dtor &);
13    void * __virtual_obj_start;
14};
15
16// the following routines are used by the compiler and should not be called directly
17static inline void __CFA_set_virt_dtor( virtual_dtor & this, void (*v_dtor)(virtual_dtor &)) {
18    this.__virtual_dtor_ptr = v_dtor;
19}
20static inline void __CFA_set_virt_start( virtual_dtor & this, void * start) {
21    this.__virtual_obj_start = start;
22}
23static inline void __CFA_setup_dtor( virtual_dtor & this ) with(this) {
24    __virtual_dtor_ptr = 0p;
25    __virtual_obj_start = &this;
26}
27static inline bool __CFA_dtor_shutdown( virtual_dtor & this ) with(this) {
28    if ( __virtual_dtor_ptr == 1p ) return true; // stop base dtors from being called twice
29    if ( __virtual_dtor_ptr ) {
30        void (*dtor_ptr)(virtual_dtor &) = __virtual_dtor_ptr;
31        __virtual_dtor_ptr = 0p;
32        dtor_ptr(*((virtual_dtor *)__virtual_obj_start)); // call most derived dtor
33        __virtual_dtor_ptr = 1p; // stop base dtors from being called twice
34        return true;
35    }
36    return false;
37}
38static inline void __CFA_virt_free( virtual_dtor & this ) { free( this.__virtual_obj_start ); }
39static inline void * __CFA_get_virt_start( virtual_dtor & this ) { return this.__virtual_obj_start; }
40static inline void ?{}( virtual_dtor & this ) {}
41static inline void ^?{}( virtual_dtor & this ) {}
Note: See TracBrowser for help on using the repository browser.