[Issue 5710] cannot use delegates as parameters to non-global template
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Mon May 6 18:58:29 PDT 2013
http://d.puremagic.com/issues/show_bug.cgi?id=5710
--- Comment #23 from Diggory <diggsey at googlemail.com> 2013-05-06 18:58:25 PDT ---
(In reply to comment #22)
> (In reply to comment #21)
>
> > The problem with Rainer's idea is that the callee would need to know the layout
> > of the stack frame in the context in which the delegate was bound, which in
> > general it cannot know.
>
> The generated function MUST know the context of main, or else it can't call
> add. Remember, add is passed as an alias, not a delegate. Even if add is
> passed as a delegate, it's calling the delegate from main's stack-frame (i.e.
> two identical calls separated by a re-assignment of the delegate would call two
> different functions).
>
> Bear in mind that each call to doStuff with a different alias is a *different*
> instantiation, even for calls with the same inner function types because of the
> alias parameter. It is OK for each instantiation to be aware of the stack
> offset for 'this'.
No, because you can call the same template instantiation with different "this"
pointers even though the "alias" parameter is the same. Each "this" pointer
will be at a different location in the stack frame, so "foo" can't possibly
know which one to use.
> And it's 2 extra words, not 1. You need to store the 'array of context
> pointers' on the stack, which you do not need if you know the layout of the
> stack frame. If you think about it, it is actually very little different from
> Kenji's idea:
>
> uint doStuff(uint a, uint b, void** this) // not void* this
> {
> // (*this + 0) points the object Foo
> // (*this + 1) points the stack frame of main()
>
> Rainer's:
>
> uint doStuff(uint a, uint b, void* this)
> {
> // this points the stack frame of main()
> // *(this + N) points the object Foo
>
> Note the difference is that N is a compile time constant, like Kenji's 1.
With Kenji's idea, you have 2 pointers on the stack:
struct multi_context {
stack_frame* base_ptr; // pointer to start of stack frame
T* this_ptr; // pointer
}
struct stack_frame {
// other stuff
multi_context context;
}
"foo" is called by passing in a pointer to the "multi_context" struct from
which both the "this_ptr" and "base_ptr" can be obtained.
With Rainer's idea, you have 1 pointer on the stack:
struct stack_frame {
// other stuff
T* this_ptr;
}
That is only a difference of one :P Rainer's idea needs a "this_ptr" on the
stack otherwise there is no way for "foo" to access it, whereas Kenji's version
doesn't.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
More information about the Digitalmars-d-bugs
mailing list