That's not at all how MetaWare implemented iterator-driven for, though.
As Joe Groff said in the headlined post, MetaWare implemented it by turning the nested body of the for statement into an anonymous nested function, which is called back (through a "full function pointer") from the iterator function whenever there's a "yield()" in that latter.
So there's no "whenever the iterator function returns". It only returns when it has finished. The body of the for statement is called by and returns to the iterator function, which is in its turn called by and returns to the function that the for statement is in.
All of the "saving state to the stack" that happens is just the quite normal mechanics of function calling, with merely some special mechanics to pass around a pointer to the lexically outer function's activation record (which is why a "full function pointer" is not a plain "function pointer") as a hidden parameter so that the (anonymous) lexically inner function knows where the outer one's automatic storage duration variables are.
MetaWare also had non-local goto from within nested functions back out into lexically enclosing scopes, and since the for statement body is a nested function, it's just a question of employing that already available implementation mechanism (which in turn does the same sorts of things as throwing exceptions does, unwinding the stack through the iterator function) for break/continue/return (and of course goto) inside the for body.
As Joe Groff said in the headlined post, MetaWare implemented it by turning the nested body of the for statement into an anonymous nested function, which is called back (through a "full function pointer") from the iterator function whenever there's a "yield()" in that latter.
So there's no "whenever the iterator function returns". It only returns when it has finished. The body of the for statement is called by and returns to the iterator function, which is in its turn called by and returns to the function that the for statement is in.
All of the "saving state to the stack" that happens is just the quite normal mechanics of function calling, with merely some special mechanics to pass around a pointer to the lexically outer function's activation record (which is why a "full function pointer" is not a plain "function pointer") as a hidden parameter so that the (anonymous) lexically inner function knows where the outer one's automatic storage duration variables are.
MetaWare also had non-local goto from within nested functions back out into lexically enclosing scopes, and since the for statement body is a nested function, it's just a question of employing that already available implementation mechanism (which in turn does the same sorts of things as throwing exceptions does, unwinding the stack through the iterator function) for break/continue/return (and of course goto) inside the for body.