digitalmars.D - non-global template fix POC WIP
- Suleyman (39/39) Jan 22 2019 Hello everyone.
- Suleyman (2/2) Jan 26 2019 I think it's ready for use. I would appreciate it if someone can
- Jonathan Marler (36/38) Jan 27 2019 I downloaded your branch and created this example that doesn't
- Jonathan Marler (25/63) Jan 27 2019 Here's another one that seems to compile, but fails at runtime
- Suleyman (3/6) Jan 27 2019 Good catch! try again it should work now.
- Timon Gehr (2/5) Jan 27 2019 Thank you!
Hello everyone. I started working on a fix for the non-global template issue. Progress at https://github.com/dlang/dmd/pull/9282 currently the following POC works: ``` struct S { int m; auto add(alias a)(int b) { return a + m + b; } auto exec(alias f)() { f(m); } } void main() { int a = 4; auto o = S(3); assert(o.add!a(2) == 4+3+2); auto dg = &o.add!a; assert(dg(7) == 4+3+7); int b; auto bSetter(int i) { b = i; } o.exec!bSetter(); assert(b == 3); /* S.add instantiated to: auto add(int b) { return main.a + main.o.m + b; } thus only requires the frame pointer of `main` */ } ``` The strategy is to access the `this` variable through the frame pointer of the caller.
Jan 22 2019
I think it's ready for use. I would appreciate it if someone can break it and produce a test case.
Jan 26 2019
On Saturday, 26 January 2019 at 12:06:48 UTC, Suleyman wrote:I think it's ready for use. I would appreciate it if someone can break it and produce a test case.I downloaded your branch and created this example that doesn't work: --------------------------------------------------------- import core.stdc.stdio : printf; struct Adder { int base; // works uint addBaseCallFunc(alias func)(uint value) { return func(base + value); } // these 2 don't work uint willNeedThreeContextPtrs(alias func)(uint value) { int localVar = func(value); uint localFunc(uint subValue) { return localVar + subValue; } return addBaseCallFuncs!(func, localFunc)(value); } uint addBaseCallFuncs(alias func1, alias func2)(uint value) { return func2(func1(base + value)); } } void main() { auto adder = Adder(3); int offset = 6; uint doOffset(uint value) { return offset + value; } // works printf("%d\n", adder.addBaseCallFunc!doOffset(4)); // need 3 context pointers (doesn't work) printf("%d\n", adder.willNeedThreeContextPtrs!doOffset(4)); }
Jan 27 2019
On Sunday, 27 January 2019 at 18:13:49 UTC, Jonathan Marler wrote:On Saturday, 26 January 2019 at 12:06:48 UTC, Suleyman wrote:Here's another one that seems to compile, but fails at runtime (it doesn't print anything): import core.stdc.stdio : printf; struct Adder { int base; uint addBaseCallFuncs(alias func1, alias func2)(uint value) { return func2(func1(base + value)); } } void main() { auto adder = Adder(3); int offset = 6; uint doOffset1(uint value) { return offset + value; } void anotherFunc() { int anotherVar = 11; uint doOffset2(uint value) { return anotherVar + value; } printf("%d\n", adder.addBaseCallFuncs!(doOffset1, doOffset2)(4)); } }I think it's ready for use. I would appreciate it if someone can break it and produce a test case.I downloaded your branch and created this example that doesn't work: --------------------------------------------------------- import core.stdc.stdio : printf; struct Adder { int base; // works uint addBaseCallFunc(alias func)(uint value) { return func(base + value); } // these 2 don't work uint willNeedThreeContextPtrs(alias func)(uint value) { int localVar = func(value); uint localFunc(uint subValue) { return localVar + subValue; } return addBaseCallFuncs!(func, localFunc)(value); } uint addBaseCallFuncs(alias func1, alias func2)(uint value) { return func2(func1(base + value)); } } void main() { auto adder = Adder(3); int offset = 6; uint doOffset(uint value) { return offset + value; } // works printf("%d\n", adder.addBaseCallFunc!doOffset(4)); // need 3 context pointers (doesn't work) printf("%d\n", adder.willNeedThreeContextPtrs!doOffset(4)); }
Jan 27 2019
On Sunday, 27 January 2019 at 18:13:49 UTC, Jonathan Marler wrote:I downloaded your branch and created this example that doesn't work: ...Good catch! try again it should work now. Thanks. Looking forward to your next case.
Jan 27 2019
On 22.01.19 23:26, Suleyman wrote:I started working on a fix for the non-global template issue.Thank you!
Jan 27 2019
On Sunday, 27 January 2019 at 22:25:20 UTC, Timon Gehr wrote:Thank you!The pleasure is mine. This was number one on my list of the most irritating limitations.
Jan 29 2019
Hello, I finished working on my solution I should be pretty solid now with a good number of unitests and corner cases covered. waiting for your replies. link: https://github.com/dlang/dmd/pull/9282 I dropped the initial strategy instead I decided to use a static array of two pointer `void*[2]*` and making this one a closure variable thus it will be GC-allocated only when the function escapes. example: ``` struct S { auto func(alias a)() { ++a; } } void noClosure() { int a; // stack allocated auto s = S(); // v implicit var `void*[2] __this;` stack allocated s.func!a(); // no closure made } void withClosure() { int a; // closure var GC allocated auto s = S(); // v implicit closure var `void*[2] __this;` GC allocated auto dg = &s.func!a; // closure made } ```
Apr 12 2019