During recent discussions at work, someone referred to a trampoline function.
I have read the description at Wikipedia. It is enough to give a general idea of the functionality, but I would like something a bit more concrete.
Do you have a simple snippet of code that would illustrate a trampoline?
There is also the LISP sense of 'trampoline' as described on Wikipedia:
Let us say we are using Javascript and want to write the naive Fibonacci function in continuation-passing-style. The reason we would do this is not relevant - to port Scheme to JS for instance, or to play with CPS which we have to use anyway to call server-side functions.
So, the first attempt is
But, running this with
n = 25
in Firefox gives an error 'Too much recursion!'. Now this is exactly the problem (missing tail-call optimization in Javascript) that trampolining solves. Instead of making a (recursive) call to a function, let usreturn
an instruction (thunk) to call that function, to be interpreted in a loop.Let me add few examples for factorial function implemented with trampolines, in different languages:
Scala:
Java:
C (unlucky without big numbers implementation):
I'll give you an example that I used in an anti-cheat patch for an online game.
I needed to be able to scan all files that were being loaded by the game for modification. So the most robust way I found to do this was to use a trampoline for CreateFileA. So when the game was launched I would find the address for CreateFileA using GetProcAddress, then I would modify the first few bytes of the function and insert assembly code that would jump to my own "trampoline" function, where I would do some things, and then I would jump back to the next location in CreateFile after my jmp code. To be able to do it reliably is a little trickier than that, but the basic concept is just to hook one function, force it to redirect to another function, and then jump back to the original function.
Edit: Microsoft has a framework for this type of thing that you can look at. Called Detours
For C, a trampoline would be a function pointer:
Edit: More esoteric trampolines would be implicitly generated by the compiler. One such use would be a jump table. (Although there are clearly more complicated ones the farther down you start attempting to generate complicated code.)
Here's an example of nested functions:
compar
can't be an external function, because it usesnbytes
, which only exists during thesort_bytes
call. On some architectures, a small stub function -- the trampoline -- is generated at runtime, and contains the stack location of the current invocation ofsort_bytes
. When called, it jumps to thecompar
code, passing that address.This mess isn't required on architectures like PowerPC, where the ABI specifies that a function pointer is actually a "fat pointer", a structure containing both a pointer to the executable code and another pointer to data. However, on x86, a function pointer is just a pointer.