C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::any::base

From: Brian Bi <bbi5291_at_[hidden]>
Date: Tue, 16 Apr 2024 14:02:07 -0400
On Tue, Apr 16, 2024 at 10:51 AM Frederick Virchanza Gotham via
Std-Proposals <std-proposals_at_[hidden]> wrote:

> On Tue, Apr 16, 2024 at 12:08 PM Frederick Virchanza Gotham wrote:
> >
> > On the Microsoft compiler, we really need to test it with the following
> class:
> >
> > class Base { int i, j; }
> > class Derived : public Base { virtual ~Derived(void){} };
> >
> > An object of type 'Derived' will be laid out in memory by the
> > Microsoft compiler as follows:
> >
> > - - - 4 bytes = i
> > - - - 4 bytes = j
> > - - - 8 bytes = pointer to vtable
>
>
> I know some of you don't want me reverse-engineering Microsoft's
> compiler here on the mailing list but we need to find out if this can
> be implemented without an ABI break. So I fed the following into
> Visual Studio 2022:
>

No one really cares about whether you're doing reverse engineering or not.

The thing is that these low-level implementation details are the least
interesting part of the proposal, and most papers include much less
low-level implementation detail than you seem to want to give. Put a small
amount of detail in the paper if you feel it's necessary in order to
convince people that the proposal is implementable. Then, focus most of
your time and energy on writing the motivation section. Then, submit the
paper. Sending us these messages that go into gory amounts of detail about
the Microsoft ABI is just a form of procrastination from the work that
actually needs to be done, and no one is reading them.


>
> struct A {
> int a, b;
> };
>
> struct B {
> float c, d;
> virtual ~B(void){}
> };
>
> struct Donkey : A, B {
> double d;
> };
>
> Donkey d;
>
> void Func(void) noexcept(false)
> {
> throw d;
> }
>
> Then I hit Ctrl + Alt + D to see the assembler generated for 'Func' as
> follows:
>
> Func:
> 1: sub rsp,48h
> 2: lea rdx,[d]
> 3: lea rcx,[rsp+20h]
> 4: call Donkey::Donkey
> 5: lea rdx,[_TI3?AUDonkey@@]
> 6: lea rcx,[rsp+20h]
> 7: call _CxxThrowException
>
> which can be explained line by line as follows:
>
> Func:
> 1: Allocate 72 bytes on the stack
> 2: Set 2nd argument to address of 'd'
> 3: Set 1st argument to address of 40 bytes of stack space
> 4: Invoke the copy-constructor of Donkey with above two arguments
> 5: Set 2nd argument to address of ThrowInfo for Donkey
> 6: Set 1st argument to address of cloned object on the stack
> 7: Call _CxxThrowException with above two arguments
>
> We can convert the above 7 instructions to the following C++ code:
>
> void Func(void) noexcept(false)
> {
> char stack_space[72u]; // Allocate space on the stack
> ::new(stack_space + 32) Donkey(&d); // Create a cloned object
> _CxxThrowException( stack_space + 32, __get_throw_info(Donkey)
> ); // Throw an exception
> }
>
> We can see the function signature of _CxxThrowException on the MSDN
> website as follows:
>
> void _CxxThrowException( void *pExceptionObject, ThrowInfo
> *pThrowInfo );
>
> There is something promising here: The function '_CxxThrowException'
> is not passed the address of the vtable pointer inside Donkey, and
> therefore it must be getting it from the ThrowInfo struct.
>
> So to summarise: It will be possible to implement this on the
> Microsoft compiler for any class type (including the most complex
> cases of virtual multiple inheritance) so long as we can utilise the
> 'type_info' to get the 'ThrowInfo'.
>
> So the missing piece now is just to come up with a function as follows:
>
> ThrowInfo const *get_ThrowInfo_from_type_info(type_info const*);
>
> I'm confident that this can be implemented, because if you look at the
> signature of "__RTDynamicCast", it's able to perform a 'dynamic_cast'
> using only the 'type_info'. So there must be a link from the type_info
> to either:
> (a) RTTICompleteObjectLocator
> or
> (b) ThrowInfo
>
> And there's probably a link from RTTICompleteObjectLocator to
> ThrowInfo. I'll disassemble "__RTDynamicCast" and try to find out how
> Microsoft is doing it, and come up with an implementation of
> std::any::base that works properly in every scenario.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>


-- 
*Brian Bi*

Received on 2024-04-16 18:02:21