Topic: run time template function generation


Author: Branimir Maksimovic <bmaxa@hotmail.com>
Date: Sat, 5 May 2007 11:15:47 CST
Raw View
When interfacing with other languages in C++ we use extern "C"
functions, for example ,
when passing pointers to them to some C api which will then callback
our code.
Problem with this is when callback is not used with our context we
can't
call member functions. Sometimes some identifier is passed to callback
function,
which can be mapped with object context but this is expensive, as each
call
costs map lookup and probably lock/unlock. In other cases there are no
identifiers
to tie our objects with.
To solve this problem I have used following procedure:
First create assembler template function which in C++ would be
something like this:
template <Object* pThis> void mycallback()
{
  pThis->member_function(); // actually this is call to extern "C"
function func(pThis);
                                         // which in turn calls member
in c++ source code
}

When creating new function I first allocate memory for it, then copy
template
function in buffer. After that I fill placeholder for template
parameter,
then adjust protection to enable execution of code in allocated page
and finally
flush CPU instruction cache.
Pointer to newly generated function is then passed as callback.
In this way I have callback that is tied to object context, no map
lookup no locking
and therefore fast code.
Problem with this is,that doing it in assembly is really simple, but
doing it
in C++ is impossible.
Another problem is that I have to make different versions for
different CPU's
and os'es. Of course, that is problem with assembler and that's why I
wish
that this can be done in high level language.

So basically I imagine something like this in C++:

class Test{
public:
Test();
void mfunction(){}
~Test();
 void (*pFunc)();
private:
  Test(const Test&);
  Test& operator=(const Test&);
};

template <Test* pThis> void callback()
{
  pThis->mfunction();
}

Test::Test()
{
  pFunc = new callback<this>;
}

Test::~Test();
{
  delete pFunc;
}

and somewhere in code:
Test t;
set_callback(t.pFunc);

To simplify implementation I would limit only to value based template
functions, so compiler just have to do same simple thing as I'm doing
it in assembly
currently.
If there is os (I can hardly imagine such) that doesn't allows this
feature,
 implementation can just issue error.

Greetings, Branimir.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Tue, 8 May 2007 02:13:30 GMT
Raw View
===================================== MODERATOR'S COMMENT:
 Apologies for the delay in moderation; this appears to be caused
by my ISP (Cox) dropping and/or blocking e-mail.


===================================== END OF MODERATOR'S COMMENT
Branimir Maksimovic ha scritto:
> When interfacing with other languages in C++ we use extern "C"
> functions, for example ,
> when passing pointers to them to some C api which will then callback
> our code.

I have to admit that I didn't fully understand your post, but it seems
to me that all you need is good function adapters and binders. You don't
need to reinvent the wheel, I'm sure you may find what suits you among
one (or more) or these:

http://boost.org/libs/bind/bind.html
http://boost.org/libs/bind/mem_fn.html
http://boost.org/doc/html/function.html
http://boost.org/libs/functional/index.html

HTH,

Ganesh

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Branimir Maksimovic <bmaxa@hotmail.com>
Date: Tue, 8 May 2007 08:41:04 CST
Raw View
===================================== MODERATOR'S COMMENT:
 Apologies for any delays in moderation; this appears to be
caused by my ISP (Cox) dropping and/or blocking e-mail.


===================================== END OF MODERATOR'S COMMENT
On May 8, 4:13 am, AlbertoBarb...@libero.it (Alberto Ganesh Barbati)
wrote:
> Branimir Maksimovic ha scritto:
>
> > When interfacing with other languages in C++ we use extern "C"
> > functions, for example ,
> > when passing pointers to them to some C api which will then callback
> > our code.
>
> I have to admit that I didn't fully understand your post, but it seems
> to me that all you need is good function adapters and binders. You don't
> need to reinvent the wheel, I'm sure you may find what suits you among
> one (or more) or these:
>
>
When dealing with C++ alone I don;t need this.
But, adapters and binders are C++ objects, they cannot be passed as
pointers to functions to some other language api.
 I need pointer to function to pass as callback.
I think along the lines of technique that is called thunking in ATL
library (implemented in assembler too)
and __closure, extension of Borland's compiler.
Also this can be used to implement lambda and
local functions
(I mean functions that are run time created by binding
some context).
When I implement this in assembler, I do repetitive work that
can be easily done by C++ compiler. And what I did is
exactly - run time value based template function
generation.

Greetings, Branimir.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Tue, 8 May 2007 16:06:27 CST
Raw View
On 8 Mai, 16:41, Branimir Maksimovic <b...@hotmail.com> wrote:
> When dealing with C++ alone I don;t need this.
> But, adapters and binders are C++ objects, they cannot be passed as
> pointers to functions to some other language api.
>  I need pointer to function to pass as callback.
> I think along the lines of technique that is called thunking in ATL
> library (implemented in assembler too)
> and __closure, extension of Borland's compiler.
> Also this can be used to implement lambda and
> local functions
> (I mean functions that are run time created by binding
> some context).
> When I implement this in assembler, I do repetitive work that
> can be easily done by C++ compiler. And what I did is
> exactly - run time value based template function
> generation.

If you want to talk between different languages, you
usually would choose the C linkage, which obviously
has no native closure type, or you would use other
languages as Java or .Net. The last one has a closure-like
type (delegate), where the first one uses normal
interfacing techniques.

So I really don't understand your aims, here, because
even if C++ would tomorrow standardize a closure type
(e.g. like Delphi has one), you could probably only use
it to talk to another module created with the same C++
compiler, because C++ has no portable binary API.

Greetings from Bremen,

Daniel Kr   gler



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Branimir Maksimovic <bmaxa@hotmail.com>
Date: Tue, 8 May 2007 22:43:55 CST
Raw View
===================================== MODERATOR'S COMMENT:

(Apologies for this moderation comment, which is here only
because of misconfigured mailservers at Cox interfering with
moderation.)


===================================== END OF MODERATOR'S COMMENT
On May 9, 12:06 am, Daniel Kr   gler <daniel.krueg...@googlemail.com>
wrote:
> On 8 Mai, 16:41, Branimir Maksimovic <b...@hotmail.com> wrote:
>
> > When dealing with C++ alone I don;t need this.
> > But, adapters and binders are C++ objects, they cannot be passed as
> > pointers to functions to some other language api.
> >  I need pointer to function to pass as callback.
> > I think along the lines of technique that is called thunking in ATL
> > library (implemented in assembler too)
> > and __closure, extension of Borland's compiler.
> > Also this can be used to implement lambda and
> > local functions
> > (I mean functions that are run time created by binding
> > some context).
> > When I implement this in assembler, I do repetitive work that
> > can be easily done by C++ compiler. And what I did is
> > exactly - run time value based template function
> > generation.
>
> If you want to talk between different languages, you
> usually would choose the C linkage, which obviously
> has no native closure type, or you would use other
> languages as Java or .Net. The last one has a closure-like
> type (delegate), where the first one uses normal
> interfacing techniques.

Linkage does not have anything to do with what function
does. Linkage is only calling convention and symbol naming
thing. One reason more to move this job to compiler.
Run time generated function is no different then
compile time generated one. Question is just who
generates function - C++ compiler or hand coded assembly.
Currently I'm doing program for windows platform,
but main job is unix. Our shop does not use Java or .Net

>
> So I really don't understand your aims, here, because
> even if C++ would tomorrow standardize a closure type
> (e.g. like Delphi has one), you could probably only use
> it to talk to another module created with the same C++
> compiler, because C++ has no portable binary API.

C++ does not have portable binary api, but every C++
implementation adopts binary api of platform it is on.
On the other hand, C++ program has to be recompiled
 on each platform.
So I can;t see the issue here? Or what linkage
and binary abi has to do with how and when is
function generated?
I think that you imagine closure as something
special, but it is not. It is just simple function
that is run time generated. It is no different
then any other compile time generated function.
Those functions can never be called outside of
module by symbol as they are run time generated
so linkage is no issue here, but they
can be called back through plain pointer to
function, and C++ compiler always use calling
convention(s) that are available on platform, or
it would be practically useless.
 I described how this can be simply implemented
and what can be done with it (eg local f.,closures,lambdas,
callbacks)

Greetings, Branimir.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Mathias Gaunard <loufoque@gmail.com>
Date: Wed, 9 May 2007 13:11:18 CST
Raw View
On May 5, 7:15 pm, Branimir Maksimovic <b...@hotmail.com> wrote:
> When interfacing with other languages in C++ we use extern "C"
> functions, for example ,
> when passing pointers to them to some C api which will then callback
> our code.
> Problem with this is when callback is not used with our context we
> can't
> call member functions.

Usually, C functions taking callbacks can take an additional void*
parameter that contains your state.

So if your C function has the signature
void register_callback(void (*do_stuff)(void*), void* param);

You can easily pass the following function and a pointer to your
object to actually use it on member functions.

void call_method(void* param)
{
     static_cast<YourClass*>(param)->yourMemberFunction();
}

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Branimir Maksimovic <bmaxa@hotmail.com>
Date: Wed, 9 May 2007 22:58:06 CST
Raw View
===================================== MODERATOR'S COMMENT:

(Apologies for this comment, which is present to bypass broken
spam filtering implemented by Cox.)


===================================== END OF MODERATOR'S COMMENT

Branimir Maksimovic wrote:
> To solve this problem I have used following procedure:
> First create assembler template function which in C++ would be
> something like this:
> template <Object* pThis> void mycallback()
> {
>   pThis->member_function(); // actually this is call to extern "C"
> function func(pThis);
>                                          // which in turn calls member
> in c++ source code
> }
>
> When creating new function I first allocate memory for it, then copy
> template
> function in buffer. After that I fill placeholder for template
> parameter,
> then adjust protection to enable execution of code in allocated page
> and finally
> flush CPU instruction cache.
> Pointer to newly generated function is then passed as callback.
> In this way I have callback that is tied to object context, no map
> lookup no locking
> and therefore fast code.

I have found that I am not alone in exploring this technique.
There are other people also working on it.
http://uebb.cs.tu-berlin.de/~magr/pub/Implementing-Closures-TR-2006.en.html
It seems that this people does similar thing, but they use it for
functional
language and they have run time compiler.
What I propose is described in their paper as:
"
In the template-based approach, program code
is pre-compiled into so-called templates. Templates consist of machine
code for
a function (or basic block, if the system works with smaller entities
than functions)
which contains holes. When instantiated, templates are copied and
holes
are patched with the constants for that particular instantiation. This
approach
is very fast, since it requires only a few instructions per generated
machine instruction,
but precludes most interesting dynamic optimizations, because of the
fixed structure of templates. Sometimes, the code-templates are not
generated
by a compiler, but written by hand, as in the Synthesis operating
system kernel
[27, 21].
"
I think that I am crystal clear now what I am trying to achieve.

Greetings, Branimir.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Wed, 9 May 2007 22:57:25 CST
Raw View
===================================== MODERATOR'S COMMENT:

(Apologies for this comment, which is present to bypass broken
spam filtering implemented by Cox.)


===================================== END OF MODERATOR'S COMMENT
On 9 Mai, 06:43, Branimir Maksimovic <b...@hotmail.com> wrote:
> > If you want to talk between different languages, you
> > usually would choose the C linkage, which obviously
> > has no native closure type, or you would use other
> > languages as Java or .Net. The last one has a closure-like
> > type (delegate), where the first one uses normal
> > interfacing techniques.
>
> Linkage does not have anything to do with what function
> does. Linkage is only calling convention and symbol naming
> thing. One reason more to move this job to compiler.
> Run time generated function is no different then
> compile time generated one. Question is just who
> generates function - C++ compiler or hand coded assembly.
> Currently I'm doing program for windows platform,
> but main job is unix. Our shop does not use Java or .Net

C++ uses the notion of "linkage" in two flavours:

1) The linkage of names (extern, static, none), which
describes a form of accessibilty of names, see (3.5/2).

2) Language linkage (linkage specifications) are described
in 7.5 and clarify that types and names have linkage.

Because you argue about other languages, the only
relevant point here is (2).

Now 7.5 can be summarized to the following: Language
linkage controls the representation of object and function
names/calling conventions, etc. Language linkage is also
integrated in the type system, therefore function types
with different language linkages are distinct types.

So your arguments that linkage "is only calling convention
and symbol naming" is not sufficient. 7.5/9 explicitly
emphasizes the point I mentioned concerning *object
layout*:

"Linkage from C + + to objects defined in other languages and to
objects defined in C + + from other languages is implementation-
defined and language-dependent. Only where the object layout
strategies of two language implementations are similar enough can
such linkage be achieved."

I don't know what you mean with "run-time generated" function,
but closures are separate types in all languages I'm aware of.
There is an already existing type in C++, which comes near
to closures, and this the member pointer type. Obviously
you have to speak about object layout, if you want to realize
interlanguage exchange of closures or any other type (even
inter-C++ if different compilers are involved, see below).

> > So I really don't understand your aims, here, because
> > even if C++ would tomorrow standardize a closure type
> > (e.g. like Delphi has one), you could probably only use
> > it to talk to another module created with the same C++
> > compiler, because C++ has no portable binary API.
>
> C++ does not have portable binary api, but every C++
> implementation adopts binary api of platform it is on.

Not true. The representation of types - even of the
fundamental types - depends on the compiler and
is often under user-control in a given compiler.
The most simple example is the fact, that practically
all compilers allow a user-customization, whether
char is signed or unsigned. A more convincing example
for the Windows OS family is that e.g. Borland and
mingw compilers support the native FPU type (80 bit)
as long double, while the Microsoft compilers chose
for long double the same representation - the 64 bit
FPU type - that is used for double. Both implementations
are conforming in this regard.
Further implemenation-defined variations are realized
via data alignment, calling conventions, class layout,
vtable layout (sometimes as separate points), member
pointer layout, etc (Especially Borland compiler provide
a mass of customization here).

> On the other hand, C++ program has to be recompiled
>  on each platform.
> So I can;t see the issue here? Or what linkage
> and binary abi has to do with how and when is
> function generated?
> I think that you imagine closure as something
> special, but it is not. It is just simple function
> that is run time generated. It is no different
> then any other compile time generated function.
> Those functions can never be called outside of
> module by symbol as they are run time generated
> so linkage is no issue here, but they
> can be called back through plain pointer to
> function, and C++ compiler always use calling
> convention(s) that are available on platform, or
> it would be practically useless.
>  I described how this can be simply implemented
> and what can be done with it (eg local f.,closures,lambdas,
> callbacks)

IMO you are mixing up the concepts of name
linkage and language linkage. If you really
mean inter-language compatibility (that was
what you described in your original posting),
then object layout is relevant and requires an
ABI contract. Closures are, in contrast to your
description *object types*, not pure function
types in the languages I know, and can be
understood as function wrappers.

I did not say that they are "special", at least
they are not more or less special as other
fundamental types (e.g. as member pointers).
A typical representation is a structure which
contains a function pointer and an object
pointer, but details differ.

It's not clear to me what you mean with a
module (here I think you speak of name
linkage, but this obviously depends on the
definition of a module) and I already disproved
your claim, that "C++ compiler always use
calling convention(s) that are available on
platform", because there usually is more
then one, see above.

Greetings from Bremen,

Daniel Kr   gler


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Branimir Maksimovic <bmaxa@hotmail.com>
Date: Thu, 10 May 2007 11:28:09 CST
Raw View
On May 9, 9:11 pm, Mathias Gaunard <loufo...@gmail.com> wrote:
> On May 5, 7:15 pm, Branimir Maksimovic <b...@hotmail.com> wrote:
>
> > When interfacing with other languages in C++ we use extern "C"
> > functions, for example ,
> > when passing pointers to them to some C api which will then callback
> > our code.
> > Problem with this is when callback is not used with our context we
> > can't
> > call member functions.
>
> Usually, C functions taking callbacks can take an additional void*
> parameter that contains your state.
>
> So if your C function has the signature
> void register_callback(void (*do_stuff)(void*), void* param);
>
> You can easily pass the following function and a pointer to your
> object to actually use it on member functions.
>
> void call_method(void* param)
> {
>      static_cast<YourClass*>(param)->yourMemberFunction();
>
> }
>
Yes, most of the api's offers additional user data to be passed.
But that's just one application. What is important that template
run time generation is low level feature that fits nicely into C++
concept and can be added to existing compilers.
Feature is quite low level, but possibilities of application are
enormous. I have found one more interesting paper on this area
which offers more application examples:
http://citeseer.ist.psu.edu/4985.html (page leads to document)
and implementation for C language:
http://phoenix.labri.fr/software/tempo/doc/tempo-doc-install.html

Greetings, Branimir.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Thu, 10 May 2007 11:28:56 CST
Raw View
> Branimir Maksimovic wrote:
> I have found that I am not alone in exploring this technique.
> There are other people also working on it.http://uebb.cs.tu-berlin.de/~magr/pub/Implementing-Closures-TR-2006.e...
> It seems that this people does similar thing, but they use it for
> functional
> language and they have run time compiler.
[..]
> I think that I am crystal clear now what I am trying to achieve.

This is some form of self-mockery, isn't it? ;-)

I just skimmed the article and observe, that it discusses
a special *implementation* technique, to realize an
efficient closure *implementation* for functional languages
(C++ is not pure functional) and with different advantages
for a special compiler technology (JIT compiler). It also
compares this ansatz with a typical closure *implementation*
(which is identical to the one I described in my second
posting).

This does by itself neither guarantee portability nor is it
related to C++ in a way that I can see. Can you explain
what the C++ relevant parts of your postings are, because
I could not recognize them?

Greetings from Bremen,

Daniel Kr   gler


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Branimir Maksimovic <bmaxa@hotmail.com>
Date: Fri, 11 May 2007 11:40:01 CST
Raw View
On May 10, 7:28 pm, Daniel Kr   gler <daniel.krueg...@googlemail.com>
wrote:
> > Branimir Maksimovic wrote:
> > I have found that I am not alone in exploring this technique.
> > There are other people also working on it.http://uebb.cs.tu-berlin.de/~magr/pub/Implementing-Closures-TR-2006.e...
> > It seems that this people does similar thing, but they use it for
> > functional
> > language and they have run time compiler.
> [..]
> > I think that I am crystal clear now what I am trying to achieve.
>
> This is some form of self-mockery, isn't it? ;-)

Obviously ;) But I hoped for that people will understand me
better.

>
> I just skimmed the article and observe, that it discusses
> a special *implementation* technique, to realize an
> efficient closure *implementation* for functional languages
> (C++ is not pure functional) and with different advantages
> for a special compiler technology (JIT compiler).

I replied to your other post, but answer is not there yet.
What I propose is feature that is used to implement
that functional language. That is: run time function
generation.

 It also
> compares this ansatz with a typical closure *implementation*
> (which is identical to the one I described in my second
> posting).
>
> This does by itself neither guarantee portability nor is it
> related to C++ in a way that I can see. Can you explain
> what the C++ relevant parts of your postings are, because
> I could not recognize them?

Relevant parts are those which mention run time code
generation, specifically that they bind context into body
of function instead of using associated structs,
 and also what I quoted (template based run time
code generation).
Of course that it is not in nature of C++ to have full run
time compiler.
What I propose is actually anti C++/CLI generics.
I don;t want new keywords; new template system;
run time compiler, required platform or anything like that.
As microsoft generics does not allow value based
generics , I want exactly opposite.
Not to allow type based templates in run time, but
only value based. This is because, then, we don't
need run time compiler at all, just code similar
to constructors that patch each object during construction.
This just extends templates, and does not changes
anything in spirit of language.
Am I clearer now?

Greetings, Branimir.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Branimir Maksimovic <bmaxa@hotmail.com>
Date: Sun, 13 May 2007 09:50:23 CST
Raw View
Branimir Maksimovic wrote:
> If there is os (I can hardly imagine such) that doesn't allows this
> feature,
>  implementation can just issue error.
>

I have talked about this with my collegue on work, and he told me that
he worked on embedded system that executes code only from ROM
while CPU is incapable to execute anything from RAM, therefore
on such systems this will not work (or any jit code generation).
Since he told me that C++ is nice to use there because of
OO (they don't use templates or exceptions), I ask
if it is possible to add feature to language that will not be
available
on machines that are unable to execute code from RAM?
If this is not possible, I'll give up ;)

Greetings, Branimir.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]