The important difference between generators/coroutines and normal
function calls is that with normal function calls, the link between
the caller and callee is fixed for the entire lifetime of the inner
frame, so there's no way for the context to shift under your feet. If
all we had were normal function calls, then (green-) thread locals
using the save/restore trick would be enough to handle all the use
cases above -- it's only for generators/coroutines where the
save/restore trick breaks down. This means that pushing/popping LCs
when crossing into/out of a generator frame is the minimum needed to
get the desired semantics, and it keeps the LC stack small (important
since lookups can be O(n) in the worst case), and it minimizes the
backcompat breakage for operations like decimal.setcontext() where
people *do* expect to call it in a subroutine and have the effects be
visible in the caller.