May 06, 2013 [Issue 5710] cannot use delegates as parameters to non-global template | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Simcha | http://d.puremagic.com/issues/show_bug.cgi?id=5710 --- Comment #20 from Steven Schveighoffer <schveiguy@yahoo.com> 2013-05-06 16:59:08 PDT --- (In reply to comment #19) > How the parameters are actually passed is fairly irrelevant, the main problem which needs to be solved is how to store two context pointers in a delegate, If you look closely at the original example, no delegates are used. add is passed by alias, not by delegate. But I see the point, if you took &foo.doStuff!add, you would be screwed. What about Rainer's idea? This would require less memory consumption from the stack. Anyone consider that this is no longer the case (in any valid solution so far)? auto dg = &foo.doStuff!add; assert(foo !is dg.ptr); Don't know if that's an unbreakable rule though... -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
May 07, 2013 [Issue 5710] cannot use delegates as parameters to non-global template | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Simcha | http://d.puremagic.com/issues/show_bug.cgi?id=5710 --- Comment #21 from Diggory <diggsey@googlemail.com> 2013-05-06 17:50:32 PDT --- (In reply to comment #20) > (In reply to comment #19) > > > How the parameters are actually passed is fairly irrelevant, the main problem which needs to be solved is how to store two context pointers in a delegate, > > If you look closely at the original example, no delegates are used. add is passed by alias, not by delegate. But I see the point, if you took &foo.doStuff!add, you would be screwed. > > What about Rainer's idea? This would require less memory consumption from the stack. > 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. If you refine it so that you arrange for part of the stack frame to follow a predefined layout so that the callee knows where to find the "this" pointer, you then need a second pointer to point to the beginning of the stack frame (because it may not be possible to place this structure at the start of the stack frame) and you end up with something that is identical to Kenji's solution. It only uses one extra pointer over what would be required if you had a dedicated 2 context pointer delegate type, so I don't think that memory consumption is much of a problem. > Anyone consider that this is no longer the case (in any valid solution so far)? > > auto dg = &foo.doStuff!add; > assert(foo !is dg.ptr); > > Don't know if that's an unbreakable rule though... That assertion is only currently valid for member function delegates. Nested functions store the frame pointer in "dg.ptr". I would say that "foo" in this case is no longer strictly a member function, but is some weird mix between a member function and an anonymous nested function, so it's perfectly reasonable to expect it to behave differently in that case. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
May 07, 2013 [Issue 5710] cannot use delegates as parameters to non-global template | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Simcha | http://d.puremagic.com/issues/show_bug.cgi?id=5710 --- Comment #22 from Steven Schveighoffer <schveiguy@yahoo.com> 2013-05-06 18:10:18 PDT --- (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'. 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. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
May 07, 2013 [Issue 5710] cannot use delegates as parameters to non-global template | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Simcha | http://d.puremagic.com/issues/show_bug.cgi?id=5710 --- Comment #23 from Diggory <diggsey@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: ------- |
May 07, 2013 [Issue 5710] cannot use delegates as parameters to non-global template | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Simcha | http://d.puremagic.com/issues/show_bug.cgi?id=5710 --- Comment #24 from Steven Schveighoffer <schveiguy@yahoo.com> 2013-05-07 05:52:41 PDT --- (In reply to comment #23) > > 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. Yes, you are right, thanks for explaining. > 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. Likely the this_ptr is repeated inside the stack frame for normal access during the function. Anyway, the point is moot since only Kenji's solution is valid. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
Copyright © 1999-2021 by the D Language Foundation