Thread overview
Object pointer from delegate
Aug 25, 2006
Lutger
Aug 26, 2006
Kirk McDonald
Aug 26, 2006
Lutger
Aug 28, 2006
BCS
Aug 28, 2006
Don Clugston
Aug 28, 2006
Craig Black
Aug 29, 2006
Don Clugston
August 25, 2006
Is it possible to obtain the object pointer from a delegate that is taken from a member function? Is it a hack?
August 26, 2006
Lutger wrote:
> Is it possible to obtain the object pointer from a delegate that is taken from a member function? Is it a hack?

Yes, it is a hack. Here's the method I use in Pyd:

struct FakeDG {
    Object instance;
    void* fn;
}

template dg_union(Dg) {
    union dg_union {
        FakeDG fake_dg;
        Dg real_dg;
    }
}

class Foo {
    void foo() { }
}

void main() {
    Foo f = new Foo;
    auto dg = &f.foo;

    dg_union!(typeof(dg)) u;
    u.real_dg = dg;

    Foo g = cast(Foo)u.fake_dg.instance;
    assert(f is g);
}

This relies on the particular way that DMD represents delegates internally, which is not (yet) a part of the spec. I don't really expect this to change any time soon, but it should still be considered a hack.

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://pyd.dsource.org
August 26, 2006
Thanks! This can be useful if needed. Imho it would be nice if there was a delegate property to get the object pointer.

Kirk McDonald wrote:
> Lutger wrote:
>> Is it possible to obtain the object pointer from a delegate that is taken from a member function? Is it a hack?
> 
> Yes, it is a hack. Here's the method I use in Pyd:
> 
> struct FakeDG {
>     Object instance;
>     void* fn;
> }
> 
> template dg_union(Dg) {
>     union dg_union {
>         FakeDG fake_dg;
>         Dg real_dg;
>     }
> }
> 
> class Foo {
>     void foo() { }
> }
> 
> void main() {
>     Foo f = new Foo;
>     auto dg = &f.foo;
> 
>     dg_union!(typeof(dg)) u;
>     u.real_dg = dg;
> 
>     Foo g = cast(Foo)u.fake_dg.instance;
>     assert(f is g);
> }
> 
> This relies on the particular way that DMD represents delegates internally, which is not (yet) a part of the spec. I don't really expect this to change any time soon, but it should still be considered a hack.
> 
August 28, 2006
Kirk McDonald wrote:
> Lutger wrote:
>> Is it possible to obtain the object pointer from a delegate that is taken from a member function? Is it a hack?
> 
> Yes, it is a hack. Here's the method I use in Pyd:
> 
> struct FakeDG {
>     Object instance;
>     void* fn;
> }
> 
> template dg_union(Dg) {
>     union dg_union {
>         FakeDG fake_dg;
>         Dg real_dg;
>     }
> }
> 
> class Foo {
>     void foo() { }
> }
> 
> void main() {
>     Foo f = new Foo;
>     auto dg = &f.foo;
> 
>     dg_union!(typeof(dg)) u;
>     u.real_dg = dg;
> 
>     Foo g = cast(Foo)u.fake_dg.instance;
>     assert(f is g);
> }
> 
> This relies on the particular way that DMD represents delegates internally, which is not (yet) a part of the spec. I don't really expect this to change any time soon, but it should still be considered a hack.

Yes, but it has been stated that it will change in DMD 2.0, when delegates and function pointers become the same. At which time it might not even be possible to get the object pointer from a delegate.

(Since the delegate will point to a thunk, it may be possible to disassemble the thunk to recover the object pointer. Maybe).
August 28, 2006
Lutger wrote:
> Thanks! This can be useful if needed. Imho it would be nice if there was a delegate property to get the object pointer.
> 

Not all delegates have a Object pointer in them.

class C
{
	int j;
	int m(){return j;}
}

int fn(bool b)
{
	int i;
	int nfn()
	{
		return i;
	}

	auto dg = b ? &nfn : &(new C).m;

		// context on dg might be an Object or a stack frame
	return dg();
}
August 28, 2006
> (Since the delegate will point to a thunk, it may be possible to disassemble the thunk to recover the object pointer. Maybe).

I've not heard about this before.  I only have a fuzzy understanding of what a thunk is.  What is the benefit of using thunks in this context?

-Craig


August 29, 2006
Craig Black wrote:
>> (Since the delegate will point to a thunk, it may be possible to disassemble the thunk to recover the object pointer. Maybe).
> 
> I've not heard about this before.  I only have a fuzzy understanding of what a thunk is.  What is the benefit of using thunks in this context?
> 
> -Craig 

In the current situation, delegates are structs with an objectpointer and a function pointer. Calling a delegate dg() = someobj.somefunc()
results in code something like:

mov ebx, dg.objectpointer
call dg.functionpointer  --> calls somefunc.

In D 2.0, delegates will just be function pointers. The equivalent code is

call [dg] --> calls thunk

thunk:
mov ebx, someobj
jmp somefunc

A major advantage is that you can pass a delegate to a C function that expects a function pointer (eg, the WindowsAPI). This is how WTL works in the C++ world. The thunk code needs to be created at run time; normally, it's created on the stack.