> either you implement them partially and have gaps in your semantics so that returning from a function whose stack frame is no longer active raises an exception
Exactly right. That's the one nasty corner case I know of. I don't know how often it comes up in practice. I believe Ruby handles it by trying to make blocks not-very-first-class so that it's hard to capture one and have its extent outlast the outer stack frames.