Date: Tue, 10 Jun 2025 10:59:41 +0100
On Tue, Jun 10, 2025 at 10:30 AM Frederick Virchanza Gotham wrote:
>
> I'm taking a look at two ABI's here: The Itanium ABI and the Microsoft
> ABI, to see what can be made possible in both.
As I said in a previous post, the address of the vtable pointer inside
a polymorphic object will always be divisible by alignof(void*),
meaning that the lower 3 bits are fair game to be used for storing
information So I'm thinking I'll use one of those bits to indicate if
the type has a virtual destructor, something like:
template<class Tref> requires is_polymorphic_v< remove_cvref_t<Tref> >
constexpr std::polyhandle(Tref &&obj) noexcept
{
typedef remove_cvref_t<Tref> T;
this->p = const_cast<T*>( addressof(obj) );
uintptr_t n = reinterpret_cast<uintptr_t>( this->p );
assert( 0u == (n % sizeof(void*)) );
n |= std::has_virtual_destructor_v<T>;
this->p = reinterpret_cast<void*>(n);
}
And from there I'll try figure out if either the Itanium ABI or the
Microsoft ABI has a way of finding the destructor's address in the
vtable (unfortunately it's not always in the first position in the
vtable -- not even on Itanium). But if can figure out a way to find
the destructor in the vtable, then I could give 'polyhandle' another
method called 'destroy', something like:
void std::polyhandle::destroy(void)
{
uintptr_t n = reinterpret_cast<uintptr_t>( this->p );
assert( n & 1u ); // ensure had virtual destructor
n -= 1u;
void *const ptr = reinterpret_cast<void*>(n);
void (*const pf)(void*) = FindDestructorAddress(ptr); // Get from ABI
assert( nullptr != pf );
pf( this->most_derived() );
}
>
> I'm taking a look at two ABI's here: The Itanium ABI and the Microsoft
> ABI, to see what can be made possible in both.
As I said in a previous post, the address of the vtable pointer inside
a polymorphic object will always be divisible by alignof(void*),
meaning that the lower 3 bits are fair game to be used for storing
information So I'm thinking I'll use one of those bits to indicate if
the type has a virtual destructor, something like:
template<class Tref> requires is_polymorphic_v< remove_cvref_t<Tref> >
constexpr std::polyhandle(Tref &&obj) noexcept
{
typedef remove_cvref_t<Tref> T;
this->p = const_cast<T*>( addressof(obj) );
uintptr_t n = reinterpret_cast<uintptr_t>( this->p );
assert( 0u == (n % sizeof(void*)) );
n |= std::has_virtual_destructor_v<T>;
this->p = reinterpret_cast<void*>(n);
}
And from there I'll try figure out if either the Itanium ABI or the
Microsoft ABI has a way of finding the destructor's address in the
vtable (unfortunately it's not always in the first position in the
vtable -- not even on Itanium). But if can figure out a way to find
the destructor in the vtable, then I could give 'polyhandle' another
method called 'destroy', something like:
void std::polyhandle::destroy(void)
{
uintptr_t n = reinterpret_cast<uintptr_t>( this->p );
assert( n & 1u ); // ensure had virtual destructor
n -= 1u;
void *const ptr = reinterpret_cast<void*>(n);
void (*const pf)(void*) = FindDestructorAddress(ptr); // Get from ABI
assert( nullptr != pf );
pf( this->most_derived() );
}
Received on 2025-06-10 09:59:53