On 1 January 2011 01:52, Erik Huelsmann ehuels@gmail.com wrote:
Minor clarification: the call stack frames are unwound rather than cleared. The stack doesn't clear completely, it unwinds to the catching frame. If any values were stored on the stack, they're gone at that point, _unless_ they were pushed before invoking the throwing operation.
That's really not what I see happening in the verification process. What I see is that the stack of the current frame gets completely cleared. There's only 1 value on the stack when an exception handler is invoked, which is the exception object. Or at least, this is what the verifier assumes. This link (10th bullet) seems to support that: "When an exception is thrown, the contents of the operand stack are discarded." [http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#1...].
Ok, it clears the operand stack, and unwinds the call stack to the frame that has the catch. The terminology is nicely overloaded. :) That explains your findings, if the opstack is cleared but local variables aren't (well, there's no reason why the latter would be).
This is my point: we are currently doing things which - if written in Java - would look like this: MyClass.execute(Symbol.KEYWORD, try { invoke_some_lisp_code(); } catch (Go g) { return-from-try ThisClass.constantValue; } ); which first puts Symbol.KEYWORD on the stack, but the stack gets cleared out when "catch (Go g)" is triggered.
It puts Symbol.KEYWORD on the operand stack, yes. We need to distinguish these ambiguities. ;) The local variables are on a different stack, which contains the stack frames, which contain the opstack and the local variables, ultimately, as far as I understand. Hence my confusion about the difference.
Right. But the frame where the exception is "handled" isn't being unwound. It's stack is being cleared though; meaning that anything that was on that stack isn't anymore. *That* is our stack inconsistency issue.
Sounds comprehensible, yes. It also sounds somewhat logical, the opstack is for building operands for an instruction, and if a throw occurs, the instruction may or may not have popped the opstack, and it's illogical to assume that anything left on the opstack would be useful for anything, as one can't reasonably know where the throw occurred and what's left on the opstack. It makes sense to me.
So yes, the catching frame of the call stack isn't unwound, but the opstack in that frame is cleared. If we're trying to assume that the opstack contains sane values in the presence of exceptions, it seems to me we're playing tricks with the jvm facilities.