Thread overview
Getting the typeid of an object disguised under an interface
Mar 28, 2016
Tomer Filiba
Mar 28, 2016
Adam D. Ruppe
Mar 28, 2016
Tomer Filiba
Mar 28, 2016
Adam D. Ruppe
March 28, 2016
In continuation of an ancient thread: http://forum.dlang.org/post/k9gu6d$2glr$1@digitalmars.com

I wanted to do something like what Gor wanted, ended up with this:

Object interfaceToObject(I)(I obj) if (is(I == interface)) {
    import object;
    return cast(Object)(cast(void*)obj - ((cast(Interface*)obj.__vptr[0]).offset));
}

writeln(interfaceToObject(ex.info))
// prints core.runtime.defaultTraceHandler.DefaultTraceInfo

By the way, the reason I need it is to get the actual callstack from the TraceInfo, so in reality it's much worse:

struct DefaultTraceInfo {
    int      numframes;
    void*[0] callstack;
}
auto traceInfo = cast(DefaultTraceInfo*)(cast(void*)(interfaceToObject(ex.info)) + (void*).sizeof * 2);

It would be really nice if TraceInfo exposed the callstack to the user. It only provides an opApply that converts to it string... adding a simple property such as

@property void*[] frames();

would be awesome.
March 28, 2016
On Monday, 28 March 2016 at 11:58:17 UTC, Tomer Filiba wrote:
> Object interfaceToObject(I)(I obj) if (is(I == interface)) {
>     import object;
>     return cast(Object)(cast(void*)obj - ((cast(Interface*)obj.__vptr[0]).offset));
> }

eeek, plain `cast(Object) obj` works for this! You don't need all that other stuff.

> It would be really nice if TraceInfo exposed the callstack to the user. It only provides an opApply that converts to it string... adding a simple property such as

You could always call the backtrace function from the debug info if you are on Linux.

http://man7.org/linux/man-pages/man3/backtrace.3.html

That's what trace info used to do. (now it does it itself but same thing)
March 28, 2016
On Monday, 28 March 2016 at 14:31:57 UTC, Adam D. Ruppe wrote:
> eeek, plain `cast(Object) obj` works for this! You don't need all that other stuff.

cool! didn't know that. it makes sense now that i think of it.

> You could always call the backtrace function from the debug info if you are on Linux.

yes, but it's used for logging exceptions. instead of doing the to-string conversion in place, we just keep the raw pointers and do addr2line on demand. so we're given an exception and need to extract the bt from it

-tomer

March 28, 2016
On Monday, 28 March 2016 at 17:40:15 UTC, Tomer Filiba wrote:
> yes, but it's used for logging exceptions. instead of doing the to-string conversion in place, we just keep the raw pointers and do addr2line on demand. so we're given an exception and need to extract the bt from it

Perhaps you can set your own trace handler and either copy/paste code from druntime or just do your own backtrace() based thing:

http://dpldocs.info/experimental-docs/core.runtime.Runtime.traceHandler.1.html


Ugh, the druntime authors didn't actually document TraceHandler (it is listed as private, but that function obviously isn't). It is:

    alias Throwable.TraceInfo function( void* ptr ) TraceHandler;


The thing it passes is typically null. So you construct your own class fitting the TraceInfo interface and this is called when an exception is built.