Messages in this thread | | | From | Stefan Monnier <monnier+/news/lists/linux/> | Subject | Re: trampolines | Date | 15 Apr 1997 20:05:03 -0400 |
| |
Matei Conovici <cmatei@lbi.ro> writes: > What are they exactly used for (and possibly why)?
It doesn't have much to do with linux-kernel, but here it goes:
say you have the following code:
some_fun (List vals) { int limit = 2; Bool my_filter (int val) { return val > limit; }
filter_out(vals, my_filter); }
the function my_filter refers to "limit" which is not a global value, but rather ta value that will sit on the stack (and maybe multiple times, maybe filter_out will even call recursively some_fun, who knows), so my_filter cannot just be a "pointer to code" but needs to encode two things: the code and the location of the "limit" variable it refers to. This is called a closure in usual parlance. Now C doesn't expect function-pointers to be such "complex" datastructure, so in order for filter_out to be able to call that closure as if it really were just a pointer-to-code, gcc creates (by copying from a template) a piece of code which wraps the my_filter closure so that when this piece of code is called from filter_out, it will call my_filter and pass it the location of the "limit" variable. This piece of code has to be created at run time and the memory space for it will naturally be allocated on the stack.
There are alternative ways to deal with this problem, but none of them are clearly superior (and this one isn't any more clearly superior to the others).
I'd (personally) prefer to have functgion-pointers be actually represented by a structure containing the address of the code and the address of the corresponding environment (in which "limit" will be found) and I believe that the PowerPC standard API uses such a scheme, but it's a pain to change such a thing (just like changing the size of "long" tends to break many things)
Stefan
| |