<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div apple-content-edited="true"><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><div style="word-wrap: break-word; -khtml-nbsp-mode: space; -khtml-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><div>On 28 Apr 2009, at 11:50, Jay wrote:</div></span></span></span></span></span></span></span></span></div></span></div><div><br class="Apple-interchange-newline"><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0; "><div class="hmmessage" style="font-size: 10pt; font-family: Verdana; ">1) Should we just always use sigsetjmp/siglongjmp?<br>Or, getting the signal mask is much extra expense usually unnecesary?<br>  (imagine the case of there being a stack walker, where not even setjmp is paid for)<br>Folks aren't supposed to muck with it willy nilly and should expect raising/catching an exception to restore to that which it was at the point of the try?</div></span></blockquote><div><br></div><div>I would have thought so, yes.  I thought I had seen use of setjmp/longjmp instead of _setjmp/_longjmp but it appears some platforms don't restore signal masks (viz. I386_DARWIN).</div><br><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0; "><div class="hmmessage" style="font-size: 10pt; font-family: Verdana; ">2) The inlined NULL checks arounds the "barrier" calls:<span class="Apple-converted-space"> </span><br>  - Aren't they just bloating the code for the unusual case?<span class="Apple-converted-space"> </span><br>  - Aren't they better left in the barrier functions themselves?<span class="Apple-converted-space"> </span><br>  - Besides leading to smaller and therefore faster code (except in the usual<br>  case of there being a NULL pointer deref, which is always going to be slow anyway),<br>  can't this then double or mostly double for a place to fix this?<br>  That is, IF, but I doubt this is true, IF every pointer deref goes through a "barrier"<br>  function, the exceptions could be raised from them, right</div></span></blockquote><div><br></div><div>The point is that we want to do a fast inline check via non-NIL references, so we need to explicitly check for those.  This is not the standard NIL check, since it is legal to load NIL from the heap.  There are no exceptions to be raised here.  The explicit check for loading NIL is only for loads from the heap.  Not for stores to the heap.</div><br><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0; "><div class="hmmessage" style="font-size: 10pt; font-family: Verdana; ">?<br> <br> <br> Are the barrier calls placed adequately maybe?????<br> I don't think they are placed for untraced derefs (a fix Tony recently put in)<br> and I imagine you might want those to act the same as traced null derefs.<br> Maybe a pragma???<br> <br> <br> - Jay<br><br> <br>> To:<span class="Apple-converted-space"> </span><a href="mailto:hosking@cs.purdue.edu">hosking@cs.purdue.edu</a><br>> Date: Mon, 27 Apr 2009 18:18:10 -0700<br>> From:<span class="Apple-converted-space"> </span><a href="mailto:mika@async.caltech.edu">mika@async.caltech.edu</a><br>> CC:<span class="Apple-converted-space"> </span><a href="mailto:m3devel@elegosoft.com">m3devel@elegosoft.com</a><br>> Subject: Re: [M3devel] RuntimeError doesn't work quite as advertised<br>><span class="Apple-converted-space"> </span><br>> I think it ought to be safe to use siglongjmp.<br>><span class="Apple-converted-space"> </span><br>> So we could attach a sigjmpbuf to whatever structure PushEFrame<br>> builds only when it's doing it for a "RuntimeError", and on a runtime<br>> error that's not handled otherwise, we catch the unix signal and<br>> call siglongjmp to get back to the exception handler...<br>><span class="Apple-converted-space"> </span><br>> Here's an example in C:<br>><span class="Apple-converted-space"> </span><br>> #include <setjmp.h><br>> #include <signal.h><br>><span class="Apple-converted-space"> </span><br>> sigjmp_buf env;<br>><span class="Apple-converted-space"> </span><br>> void handler(int x) { siglongjmp(env,1); }<br>><span class="Apple-converted-space"> </span><br>> main()<br>> {<br>> signal(SIGSEGV, handler);<br>><span class="Apple-converted-space"> </span><br>> if(sigsetjmp(env,1)) {<br>> printf("caught signal\n");<br>> exit(0);<br>> } else {<br>> printf("initialized env\n");<br>> }<br>><span class="Apple-converted-space"> </span><br>> {<br>> int *a=(void *)0;<br>> printf("a is %d\n", *a /* SEGV */);<span class="Apple-converted-space"> </span><br>> /* not reached */<br>> }<br>> }<br>><span class="Apple-converted-space"> </span><br>> Mika<br>><span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> Tony Hosking writes:<br>> >It's probably not generally safe to use RAISE inside a signal<span class="Apple-converted-space"> </span><br>> >handler. There are esoteric rules as to what signal handlers can<span class="Apple-converted-space"> </span><br>> >handle...<br>> ><br>> >I think we need to think harder on how best to reflect NIL dereference<span class="Apple-converted-space"> </span><br>> >as a signal. Perhaps we need explicit NIL checks after all...<br>> ><br>> >On 27 Apr 2009, at 18:31, Mika Nystrom wrote:<br>> ><br>> >> Ok so I tried the "obvious thing", namely, I changed RTSignal.SegV to<br>> >> do<br>> >><br>> >> RAISE RuntimeError.E(RuntimeError.T.BadMemoryReference);<br>> >><br>> >> Somewhat to my surprise, this does the right thing for a null method.<br>> >> But somewhat less surprisingly, it loops for NilJump and NilDeref.<br>> >> Is the machine jumping back and re-executing the same instructions<br>> >> after the signal handler returns?<br>> >><br>> >> Would all hell break loose if one were to special-case EXCEPT<br>> >> RuntimeError.E to store a thread-local jmp_buf that one does a<br>> >> C-style longjmp to? (With a chain back to any higher RuntimeError.E<br>> >> handlers, I suppose...) Or is there a way to get the exception to<br>> >> work out of the signal handler with the normal exception mechanism?<br>> >><br>> >> Mika<br>> ><br>> >> Mika Nystrom writes:<br>> >>><br>> >>> Maybe someone else knows more about this than me...<br>> >>><br>> >>> The following program:<br>> >>><br>> >>> MODULE Main;<br>> >>> IMPORT RuntimeError, IO;<br>> >>><br>> >>> PROCEDURE Range() = BEGIN EVAL VAL(-1,CARDINAL) END Range;<br>> >>><br>> >>> PROCEDURE Assert() = BEGIN <*ASSERT FALSE*> END Assert;<br>> >>><br>> >>> PROCEDURE NilJump() = VAR x : PROCEDURE() := NIL; BEGIN x() END<span class="Apple-converted-space"> </span><br>> >>> NilJump;<br>> >>><br>> >>> PROCEDURE NilDeref() =<br>> >>> VAR x : REF INTEGER := NIL; b : INTEGER;<br>> >>> BEGIN b := x^ END NilDeref;<br>> >>><br>> >>> PROCEDURE NilMethod() =<br>> >>> TYPE T = OBJECT METHODS m() END;<br>> >>> VAR t : T; BEGIN t.m() END NilMethod;<br>> >>><br>> >>> BEGIN<br>> >>> WITH ps = ARRAY OF PROCEDURE() { Range, Assert, NilMethod, NilJump,<span class="Apple-converted-space"> </span><br>> >>> NilDeref } DO<br>> >>> FOR i := FIRST(ps) TO LAST(ps) DO<br>> >>> TRY<br>> >>> ps[i]()<br>> >>> EXCEPT<br>> >>> RuntimeError.E(e) => IO.Put("RuntimeError: " &<span class="Apple-converted-space"> </span><br>> >>> RuntimeError.Tag(e) & " \n")<br>> >>> END<br>> >>> END<br>> >>> END<br>> >>> END Main.<br>> >>><br>> >>> yields the following result:<br>> >>><br>> >>> (1053)trs80:~/test/src>../FreeBSD4/prog<br>> >>> RuntimeError: An enumeration or subrange value was out of range.<br>> >>> RuntimeError: <*ASSERT*> failed.<br>> >>><br>> >>><br>> >>> ***<br>> >>> *** runtime error:<br>> >>> *** Segmentation violation - possible attempt to dereference NIL<br>> >>> *** pc = 0x8048a71 = NilMethod + 0x10 in ../src/Main.m3<br>> >>> ***<br>> >>><br>> >>> Abort<br>> >>><br>> >>> Seems to me I ought to see a few more exceptions and not a crash.<br>> >>><br>> >>> I'm happy to investigate a bit more, but does anyone have a clue<span class="Apple-converted-space"> </span><br>> >>> where<br>> >>> to begin?<br>> >>><br>> >>> Mika<br></div></span></blockquote></div><br></body></html>