A question about method signature template parameters

3 views
Skip to first unread message

avasilev

unread,
Dec 7, 2011, 7:10:49 AM12/7/11
to v8-juice-js-dev
Hi Stephan,
I m back to v8 now. I have developed my own binding, featuring some
things that I specifically need - mainly multithreading and now I
would need to be able to bind a method, which is inherited by the
bound class. What I have until now is a bit low-level, centered around
a templated class, but otherwise does not use much templates, but
macros. I needed this low-level to be able for example to have js
functions with variable arguments or with arguments that can be a
different type. However now I need a more straightforward wrapping
solution that directly translates to a native class - this will make
crating bindings for existing libraries much easier. For this, I am
going to use more templates, and here is my question. In cvv8, for
MethodToInCa - family of templates, you specify the native method
prototype via the function-like notation, e.g. int(char, float). This
signature is not directly compatible with a method signature, e.g.
int(T::*)(char, float). Also, I would need to extract the argument
types one by one from such a signature. I tried to fund out how you do
it, but your code, even though very clean and well documented, is too
much for my experience with templates. So my question is - how can it
be done?

Stephan Beal

unread,
Dec 7, 2011, 1:18:18 PM12/7/11
to v8-juic...@googlegroups.com
On Wed, Dec 7, 2011 at 1:10 PM, avasilev <alxva...@gmail.com> wrote:
would need to be able to bind a method, which is inherited by the
bound class.

Hiho!

If you figure out a good way to do that let me know. i don't think my current binding code can do that. If your class binding mechanism is in a usable state i'd love to see it.

What I have until now is a bit low-level, centered around
a templated class, but otherwise does not use much templates, but
macros. I needed this low-level to be able for example to have js
functions with variable arguments or with arguments that can be a
different type.

cvv8 can do that to some degree:

 
...MethodToInCa - family of templates, you specify the native method

prototype via the function-like notation, e.g. int(char, float). This
signature is not directly compatible with a method signature, e.g.
int(T::*)(char, float).  Also, I would need to extract the argument
types one by one from such a signature.

The synax (returnType (arg1,arg2)) is really just a convenience form which gets  internally translated, via template specializations, to (returnType (T::*)(arg1,arg2)), and the templates do in fact provide enough type information to extract the parts you're looking for. Can you show me your (hypothetical) use case? From that i should be able to figure out which template(s) might be most helpful. The framework-level code can tell you the argument count and types and such, but what they can't do is transform from one argument count to another, e.g.: int T::foo(int, int) ---> int T::foo(int), because there is syntactically no way to do this at the level which cvv8 works (maybe it can be done in C++0x, but i haven't tried).

 
I tried to fund out how you do
it, but your code, even though very clean and well documented, is too
much for my experience with templates. So my question is - how can it
be done?

Unfortunately the cvv8 build tree is in a broken state at the moment (a piece was removed a few days ago but still referenced in a couple places), so i can't throw together an example for you, but let's see if i can find some example code...

See examples/ConvertDemo.cpp and search for:

    void test_new_typelist()

that function contains examples of using the function signature templates, including getting their arity, class type, and arg types. compile_time_assertions() might also be useful.

Warning: if you want to actually compile the code you'll need to backrev to r2768 or earlier. i'll try to get around to fixing r2169 this weekend. Coen removed some ugly bits but some of the test/demo code still uses those ugly bits and i need to fix them to work without those bits.

--
----- stephan beal
http://wanderinghorse.net/home/stephan/

avasilev

unread,
Dec 8, 2011, 1:34:01 PM12/8/11
to v8-juice-js-dev
Heyas :)

> If you figure out a good way to do that let me know. i don't think my
> current binding code can do that.

Should be doable, what do you think is the difficulty?

> If your class binding mechanism is in a
> usable state i'd love to see it.

I am currently working on it, still not even compiled anything. I will
send you the code when
I'm ready with something working.
The lower-level layer binding class is based on something they seem to
call "curiously recurring template pattern":
http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
I remember that I asked you if this approach is portable, or is just a
something that
the particular compiler lets me do. You said it seems fairly portable.
Indeed,
it seems it's quite heavily used in practice.
With the lower-layer, to implement bindings to existing libraries, I
had the wrapper
class proxy the calls from the wrapper to the native library's API,
it's nothing special. I
implemented a lot of convenience macros to ease this task, but still
this is quite tedious.
Hence the higher layer that I decided to implement.
The basic idea there is to have two native classes - a 'wrapper' and a
' native'.
The native is a class that is not aware of V8, and the wrapper is a
glue between
v8 and the native. So far, the lower-level layer had only the notion
of 'wrapper', and all native
implementation was in that wrapper.

Wow, I have seen the arity dispatcher mentioned, but didn't know cvv8
was able to dispatch
based on argument type. I should look at the code, but I'm not sure
if I will understand
how it is done with all the template tricks:)


>The synax (returnType (arg1,arg2)) is really just a convenience form which
>gets internally translated, via template specializations, to (returnType
>(T::*)(arg1,arg2)), and the templates do in fact provide enough type
>information to extract the parts you're looking for. Can you show me your
>(hypothetical) use case?

I am trying to build something universal like MethodToInCa, and would
love to have the method signature specified
in this way. Currently I specify it via separate template arguments.


>See examples/ConvertDemo.cpp and search for:
> void test_new_typelist()

These are examples for the user, I was trying to understand how it is
implemented.

>The framework-level code can tell you the argument count and types and such

Isn't the signature in question a single atomic typename template
argument? How can it be broken down?
I exampiend the code in signature_core.hpp and
signature_generated.hpp, but I couldnt find
the place where the signature is broken down to separate types. I saw
template recursion,
but this was in the case where arguments are provided as separate
template params.

Is it possible to post files here? I'd like to send you my existing
implementation

Greetings
Alex

Stephan Beal

unread,
Dec 8, 2011, 1:51:06 PM12/8/11
to v8-juic...@googlegroups.com
On Thu, Dec 8, 2011 at 7:34 PM, avasilev <alxva...@gmail.com> wrote:
Heyas :)

> If you figure out a good way to do that let me know. i don't think my
> current binding code can do that.
Should be doable, what do you think is the difficulty?

i unfortunately can't even guess because i'm not sure how i could/should tell a template that it should be able to do that. It "must somehow be possible," but i don't know how to do it.
 
call "curiously recurring template pattern":
http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
 
The good old CRTP :).
 
Hence the higher layer that I decided to implement.
The basic idea there is to have two native classes - a 'wrapper' and a
' native'.
The native is a class that is not aware of V8, and the wrapper is a
glue between
v8 and the native. So far, the lower-level layer had only the notion
of 'wrapper', and all native
implementation was in that wrapper.

i like that idea. i'd love to take a look at what you've got (or what you end up implementing). The class binding code which comes with cvv8 is basically just proof-of-concept/demo code - it does not try to be a universal solution to the problem (e.g. it cannot handle the derived method problem, or at least i don't think it can).

 
Wow, I have seen the arity dispatcher mentioned, but didn't know cvv8
was able to dispatch
 based on argument type.

It can dispatch based on any logic which we can formulate as a functor :).

>See examples/ConvertDemo.cpp and search for:
>   void test_new_typelist()

These are examples for the user, I was trying to understand how it is
implemented.

>The framework-level code can tell you the argument count and types and such

Isn't the signature in question a single atomic typename template
argument? How can it be broken down?
I exampiend the code in signature_core.hpp and
signature_generated.hpp, but I couldnt find
the place where the signature is broken down to separate types. I saw
template recursion,

Aha - that's a good question. For that, see signature_core.hpp and search for "namespace sl" (sl=="signature list"). The various templates in that namespace work with the Signature type (and its derivatives, like MethodSignature) to do things like get the arity the argument type at a given position. e.g.

typedef MethodSignature< MyType, void (int) > Sig;

int arity = sl::Arity<Sig>::Value;
typedef sl::At<0, Sig>::Type Arg0Type; // == int
bool thisIsTrue = sl::IsMethod<Sig>::Value;
bool thisIsFalse = sl::IsConstMethod<Sig>::Value;

Is it possible to post files here? I'd like to send you my existing
implementation

i'm not sure - never tried. You can also send them to me off-list if you like.

avasilev

unread,
Dec 8, 2011, 2:52:24 PM12/8/11
to v8-juice-js-dev
> Aha - that's a good question.
> For that, see signature_core.hpp and search
> for "namespace sl" (sl=="signature list"). The various templates in that
> namespace work with the Signature type (and its derivatives, like
> MethodSignature) to do things like get the arity the argument type at a
> given position. e.g.
>
> typedef MethodSignature< MyType, void (int) > Sig;
>
> int arity = sl::Arity<Sig>::Value;
> typedef sl::At<0, Sig>::Type Arg0Type; // == int
> bool thisIsTrue = sl::IsMethod<Sig>::Value;
> bool thisIsFalse = sl::IsConstMethod<Sig>::Value;
>
Thanks, I will take a look at it.
Reply all
Reply to author
Forward
0 new messages