www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - typed vtable

reply Harry Vennik <htvennik zonnet.nl> writes:
Hi,

One of the things D claims is that it eliminates the need for IDL. And yeah, it
does a lot in that direction, but I found something that's missing while trying
to actually implement some sense of RPC...

To get a good view of an interface that can be used to construct the necessary
stub code, you need to have a typed vtable. And D almost provides it... You can
get the untyped vtable, you can get a typed list of virtual function overloads
by name, and you can get the names of all interface members... So you can get
all what's needed, except that there is no way to know the vtable index of a
member function!!!

My proposal to fix this is to allow an expression like:

__traits(getVirtualFunctions, T)           // no second argument!

where T is an interface or class type (or an expression of such a type). Such
an expression should then return all virtual member functions in vtable order,
thus making it possible to relate the function itself to its vtable index.

Regards,

Harry Vennik
Nov 17 2008
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2008-11-17 13:56:55 -0500, Harry Vennik <htvennik zonnet.nl> said:

 Hi,
 
 One of the things D claims is that it eliminates the need for IDL. And 
 yeah, it does a lot in that direction, but I found something that's 
 missing while trying to actually implement some sense of RPC...
 
 To get a good view of an interface that can be used to construct the 
 necessary stub code, you need to have a typed vtable. And D almost 
 provides it... You can get the untyped vtable, you can get a typed list 
 of virtual function overloads by name, and you can get the names of all 
 interface members... So you can get all what's needed, except that 
 there is no way to know the vtable index of a member function!!!
 
 My proposal to fix this is to allow an expression like:
 
 __traits(getVirtualFunctions, T)           // no second argument!
 
 where T is an interface or class type (or an expression of such a 
 type). Such an expression should then return all virtual member 
 functions in vtable order, thus making it possible to relate the 
 function itself to its vtable index.

Personally, I had to work around the same problem in the D/Objective-C bridge and thus I could probably simplify a few things by having this, except that what I need in my case is always the vtable index of a particular function. I guess it could be implemented from the above __traits syntax, but I'd wish for a simpler solution to my problem, such as: __traits(getVTableIndex, T.foo); along with a way to check if a function is virtual, possibly by checking they're not final: static if (is(T.foo == final)) ...; This way I could build a pointer template-struct to a virtual member function (without knowing the target object in advance as with delegates). -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Nov 18 2008
next sibling parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Tue, 18 Nov 2008 17:17:36 +0300, Michel Fortin  
<michel.fortin michelf.com> wrote:

 On 2008-11-17 13:56:55 -0500, Harry Vennik <htvennik zonnet.nl> said:

 Hi,
  One of the things D claims is that it eliminates the need for IDL. And  
 yeah, it does a lot in that direction, but I found something that's  
 missing while trying to actually implement some sense of RPC...
  To get a good view of an interface that can be used to construct the  
 necessary stub code, you need to have a typed vtable. And D almost  
 provides it... You can get the untyped vtable, you can get a typed list  
 of virtual function overloads by name, and you can get the names of all  
 interface members... So you can get all what's needed, except that  
 there is no way to know the vtable index of a member function!!!
  My proposal to fix this is to allow an expression like:
  __traits(getVirtualFunctions, T)           // no second argument!
  where T is an interface or class type (or an expression of such a  
 type). Such an expression should then return all virtual member  
 functions in vtable order, thus making it possible to relate the  
 function itself to its vtable index.

Personally, I had to work around the same problem in the D/Objective-C bridge and thus I could probably simplify a few things by having this, except that what I need in my case is always the vtable index of a particular function. I guess it could be implemented from the above __traits syntax, but I'd wish for a simpler solution to my problem, such as: __traits(getVTableIndex, T.foo); along with a way to check if a function is virtual, possibly by checking they're not final: static if (is(T.foo == final)) ...; This way I could build a pointer template-struct to a virtual member function (without knowing the target object in advance as with delegates).

What if class T has multiple foo() overloads, half of which are virtual and half are not?
Nov 18 2008
parent Harry Vennik <htvennik zonnet.nl> writes:
Denis Koroskin Wrote:

 On Tue, 18 Nov 2008 17:17:36 +0300, Michel Fortin  
 <michel.fortin michelf.com> wrote:
 
 On 2008-11-17 13:56:55 -0500, Harry Vennik <htvennik zonnet.nl> said:

 Hi,
  One of the things D claims is that it eliminates the need for IDL. And  
 yeah, it does a lot in that direction, but I found something that's  
 missing while trying to actually implement some sense of RPC...
  To get a good view of an interface that can be used to construct the  
 necessary stub code, you need to have a typed vtable. And D almost  
 provides it... You can get the untyped vtable, you can get a typed list  
 of virtual function overloads by name, and you can get the names of all  
 interface members... So you can get all what's needed, except that  
 there is no way to know the vtable index of a member function!!!
  My proposal to fix this is to allow an expression like:
  __traits(getVirtualFunctions, T)           // no second argument!
  where T is an interface or class type (or an expression of such a  
 type). Such an expression should then return all virtual member  
 functions in vtable order, thus making it possible to relate the  
 function itself to its vtable index.

Personally, I had to work around the same problem in the D/Objective-C bridge and thus I could probably simplify a few things by having this, except that what I need in my case is always the vtable index of a particular function. I guess it could be implemented from the above __traits syntax, but I'd wish for a simpler solution to my problem, such as: __traits(getVTableIndex, T.foo); along with a way to check if a function is virtual, possibly by checking they're not final: static if (is(T.foo == final)) ...; This way I could build a pointer template-struct to a virtual member function (without knowing the target object in advance as with delegates).

What if class T has multiple foo() overloads, half of which are virtual and half are not?

Michel's proposed solution won't work then... I have also run into the question 'how to select a particular overload' and realised that probably that is the reason why the __traits are designed as a two-level approach: first get the member names, then get the virtual overloads of each... The possibility that someone might also want all virtual methods in vtable order seems to be just forgotten. By the way, I think that my proposal will also solve Michel's problem, as it is very similar to mine. The language bindings can also be generated from a tuple of functions. The index in the tuple is the vtable index... Although it might be off by one, because D uses index 0 of the vtable to store a reference to the ClassInfo (I never understood why... but it is a fact...). Please note that for my solution to work, it is also required that the order of functions in the vtable is defined, because recompilation of the same source must result in the same vtable order again. (I'd define the order like: in source order, and 'base' class/interface before 'derived' class/interface.) I don't know if this is actually defined now...
Nov 18 2008
prev sibling parent reply "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Tue, Nov 18, 2008 at 9:17 AM, Michel Fortin
<michel.fortin michelf.com> wrote:
 On 2008-11-17 13:56:55 -0500, Harry Vennik <htvennik zonnet.nl> said:

 Hi,

 One of the things D claims is that it eliminates the need for IDL. And
 yeah, it does a lot in that direction, but I found something that's missing
 while trying to actually implement some sense of RPC...

 To get a good view of an interface that can be used to construct the
 necessary stub code, you need to have a typed vtable. And D almost provides
 it... You can get the untyped vtable, you can get a typed list of virtual
 function overloads by name, and you can get the names of all interface
 members... So you can get all what's needed, except that there is no way to
 know the vtable index of a member function!!!

 My proposal to fix this is to allow an expression like:

 __traits(getVirtualFunctions, T)           // no second argument!

 where T is an interface or class type (or an expression of such a type).
 Such an expression should then return all virtual member functions in vtable
 order, thus making it possible to relate the function itself to its vtable
 index.

Personally, I had to work around the same problem in the D/Objective-C bridge and thus I could probably simplify a few things by having this, except that what I need in my case is always the vtable index of a particular function. I guess it could be implemented from the above __traits syntax, but I'd wish for a simpler solution to my problem, such as: __traits(getVTableIndex, T.foo); along with a way to check if a function is virtual, possibly by checking they're not final: static if (is(T.foo == final)) ...; This way I could build a pointer template-struct to a virtual member function (without knowing the target object in advance as with delegates).

A pointer template-struct to a virtual member function without knowing the target object in advance? Something like this: http://codepad.org/SXIP2jBL ?
Nov 18 2008
parent Michel Fortin <michel.fortin michelf.com> writes:
On 2008-11-18 10:17:20 -0500, "Jarrett Billingsley" 
<jarrett.billingsley gmail.com> said:

 A pointer template-struct to a virtual member function without knowing
 the target object in advance?
 
 Something like this: http://codepad.org/SXIP2jBL ?

Yeah, I was experimenting with this method while you wrote this. The sad thing about it is that you need to specify the name of the function as a string instead of an alias... meaning that a typo will create an error inside the template's code. Well I've found a trick to avoid that: template FunctionName(alias f) { const string FunctionName = (&f).stringof[0..$-2]; } Using this template, you can get the name of a function from an alias, but that's mostly a hack. And also, you can't create such a "pointer" to a private or protected method and give it to another template that lives outside the class: the mixin just won't work there because of the protection attribute. But your template is pretty neat. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Nov 19 2008