digitalmars.D - implicitly convert function pointers to delegates
- Moritz Warning (19/19) Oct 26 2008 Hi,
- KennyTM~ (15/38) Oct 26 2008 vote++ for implicit conversion. An FP can be *safely* converted to any D...
- Jarrett Billingsley (3/42) Oct 26 2008 The calling conventions for functions and delegates is different.
- KennyTM~ (3/52) Oct 26 2008 I see. And indeed it does not work if I change float to int -- the
- Frits van Bommel (12/40) Oct 26 2008 Floats are passed differently.
- Walter Bright (2/3) Oct 26 2008 Because floats are not passed in EAX, they are passed on the stack.
- downs (1/1) Oct 26 2008 When asked to convert a function pointer to a delegate, the compiler cou...
- Jarrett Billingsley (3/4) Oct 26 2008 Which is precisely what I suggested here:
- downs (2/8) Oct 27 2008 Sorry :) I wasn't aware of that.
- ore-sama (8/9) Oct 27 2008 Interestingly, on x86-32 this stub can be generated only once and placed...
Hi, some people discovered that functions can be wrapped into delegates without allocation. Here is one out of several similar solutions: R delegate(T) toDg(R, T...)(R function(T) fp) { struct dg { R opCall(T t) { return (cast(R function(T)) this) (t); } } R delegate(T) t; t.ptr = fp; t.funcptr = &dg.opCall; return t; } I would like to ask if we can get this into the language? It would make working with delegates and function pointers much more easier when function pointers implicitly convert to delegates when they "have to".
Oct 26 2008
Moritz Warning wrote:Hi, some people discovered that functions can be wrapped into delegates without allocation. Here is one out of several similar solutions: R delegate(T) toDg(R, T...)(R function(T) fp) { struct dg { R opCall(T t) { return (cast(R function(T)) this) (t); } } R delegate(T) t; t.ptr = fp; t.funcptr = &dg.opCall; return t; } I would like to ask if we can get this into the language? It would make working with delegates and function pointers much more easier when function pointers implicitly convert to delegates when they "have to".vote++ for implicit conversion. An FP can be *safely* converted to any DGs. BTW, alias float delegate (in float) DG; float area (in float radius) { float r2 = radius * radius; return 3.1415926535 * radius; } DG x; x.ptr = null; x.funcptr = &area; // writefln(typeof(x.funcptr).stringof); // ensure it's an FP not DG. writefln(x(10)); // writes 314.159 without any error. Why this simpler solution is not used? The function pointer can't touch the frame pointer anyway (an FP cannot access stuff outside its scope).
Oct 26 2008
On Sun, Oct 26, 2008 at 2:11 PM, KennyTM~ <kennytm gmail.com> wrote:Moritz Warning wrote:The calling conventions for functions and delegates is different. This method does not work in the general case.Hi, some people discovered that functions can be wrapped into delegates without allocation. Here is one out of several similar solutions: R delegate(T) toDg(R, T...)(R function(T) fp) { struct dg { R opCall(T t) { return (cast(R function(T)) this) (t); } } R delegate(T) t; t.ptr = fp; t.funcptr = &dg.opCall; return t; } I would like to ask if we can get this into the language? It would make working with delegates and function pointers much more easier when function pointers implicitly convert to delegates when they "have to".vote++ for implicit conversion. An FP can be *safely* converted to any DGs. BTW, alias float delegate (in float) DG; float area (in float radius) { float r2 = radius * radius; return 3.1415926535 * radius; } DG x; x.ptr = null; x.funcptr = &area; // writefln(typeof(x.funcptr).stringof); // ensure it's an FP not DG. writefln(x(10)); // writes 314.159 without any error. Why this simpler solution is not used? The function pointer can't touch the frame pointer anyway (an FP cannot access stuff outside its scope).
Oct 26 2008
Jarrett Billingsley wrote:On Sun, Oct 26, 2008 at 2:11 PM, KennyTM~ <kennytm gmail.com> wrote:I see. And indeed it does not work if I change float to int -- the arguments are shifted by 4 bytes to the left. (How come float works??)Moritz Warning wrote:The calling conventions for functions and delegates is different. This method does not work in the general case.Hi, some people discovered that functions can be wrapped into delegates without allocation. Here is one out of several similar solutions: R delegate(T) toDg(R, T...)(R function(T) fp) { struct dg { R opCall(T t) { return (cast(R function(T)) this) (t); } } R delegate(T) t; t.ptr = fp; t.funcptr = &dg.opCall; return t; } I would like to ask if we can get this into the language? It would make working with delegates and function pointers much more easier when function pointers implicitly convert to delegates when they "have to".vote++ for implicit conversion. An FP can be *safely* converted to any DGs. BTW, alias float delegate (in float) DG; float area (in float radius) { float r2 = radius * radius; return 3.1415926535 * radius; } DG x; x.ptr = null; x.funcptr = &area; // writefln(typeof(x.funcptr).stringof); // ensure it's an FP not DG. writefln(x(10)); // writes 314.159 without any error. Why this simpler solution is not used? The function pointer can't touch the frame pointer anyway (an FP cannot access stuff outside its scope).
Oct 26 2008
KennyTM~ wrote:Jarrett Billingsley wrote:Floats are passed differently. For instance, DMD will put the first argument into EAX if it's an int or pointer (including x.ptr in your code), while it passes floats on the stack. My x86-64 GDC passes a float in a floating-point register, while ints and pointers go into general-purpose registers (until it runs out of appropriate registers for that function call, anyway). So on both compilers floats will "work" because they're not moved elsewhere by an extra pointer at the front of the parameter list (which is essentially what happens when you call a function through a delegate's function pointer) while passing in an extra null means the first int an unsuspecting function reads is 0.On Sun, Oct 26, 2008 at 2:11 PM, KennyTM~ <kennytm gmail.com> wrote:I see. And indeed it does not work if I change float to int -- the arguments are shifted by 4 bytes to the left. (How come float works??)BTW, alias float delegate (in float) DG; float area (in float radius) { float r2 = radius * radius; return 3.1415926535 * radius; } DG x; x.ptr = null; x.funcptr = &area; // writefln(typeof(x.funcptr).stringof); // ensure it's an FP not DG. writefln(x(10)); // writes 314.159 without any error. Why this simpler solution is not used? The function pointer can't touch the frame pointer anyway (an FP cannot access stuff outside its scope).The calling conventions for functions and delegates is different. This method does not work in the general case.
Oct 26 2008
KennyTM~ wrote:(How come float works??)Because floats are not passed in EAX, they are passed on the stack.
Oct 26 2008
When asked to convert a function pointer to a delegate, the compiler could create a small stub that converts from delegate calling convention to FP calling convention, then put that stub in .funcptr and the FP in .ptr.
Oct 26 2008
On Sun, Oct 26, 2008 at 11:39 PM, downs <default_357-line yahoo.de> wrote:When asked to convert a function pointer to a delegate, the compiler could create a small stub that converts from delegate calling convention to FP calling convention, then put that stub in .funcptr and the FP in .ptr.Which is precisely what I suggested here: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=78727
Oct 26 2008
Jarrett Billingsley wrote:On Sun, Oct 26, 2008 at 11:39 PM, downs <default_357-line yahoo.de> wrote:Sorry :) I wasn't aware of that.When asked to convert a function pointer to a delegate, the compiler could create a small stub that converts from delegate calling convention to FP calling convention, then put that stub in .funcptr and the FP in .ptr.Which is precisely what I suggested here: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=78727
Oct 27 2008
downs Wrote:When asked to convert a function pointer to a delegate, the compiler could create a small stub that converts from delegate calling convention to FP calling convention, then put that stub in .funcptr and the FP in .ptr.Interestingly, on x86-32 this stub can be generated only once and placed before function prologue (and exported): Delegate stub: pop eax Function prologue: push ebp mov ebp, esp if last parameter is not stored in eax, their calling conventions are compatible and stub is empty :)
Oct 27 2008