I don't understand why trampolines are needed at all, I would think you could pass the stack reference (or the captured variables references) as extra argument to the nested function, and pass them around together with it's address as a struct. Isn't this what lambdas do in C++?
Because your callee is stupid, and it doesn't know about your extra argument. The pointer you give it needs to look like a normal function pointer in every way: it can't take different parameters, it can't return something else, and it can't move around. Almost all languages with first-class closures do it the way you mention, but the limitation is that you can't use them with code that's not expecting it.