Hi Ville,
On Sat, Jan 1, 2011 at 1:08 AM, Ville Voutilainen ville.voutilainen@gmail.com wrote:
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.
Heh. Good thing we have established the meaning of the JVM vocabulary here :-)
[snipped]
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.
Right. Well, the fact isn't so much that we're expecting sane values to in the presence of exceptions; it's more that we currently have infrastructure to 'roughly' estimate if there may be exception-related special forms in the code to be compiled. However, this infrastructure only provides estimates, trying to err on the safe side. It does err on the safe side, marking most potential situations (and many more) as 'unsafe'. However, since we still see stack inconsistency errors, my guess is that we need an exact solution (instead of the current estimate).
The solution - which is in my proposal - is to stop rewriting code in pass1, but address the true issue in pass2, where the actual issue can accurately be detected.
Bye,
Erik.