<html><head><base href="x-msg://2361/"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">That is overkill and not particularly modular.<div><div>I'd prefer to keep the changes as localised as possible.</div><div><br><div><div>On Feb 8, 2011, at 5:41 PM, Jay K wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; 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: 0px; font-size: medium; "><div class="hmmessage" style="font-size: 10pt; font-family: Tahoma; ">"Are you sure?"<br>I mean, are you sure the right thing wouldn't be to declare Variables in Try*.Parse or Try*.Check?<br>Possibly they'll even be at a high enough scope as to be correct?<br> <br> <br>ie: they don't really have to be at the function scope, as long as they are just outside the try and the except/finally...depending on how except/finally are generated..ok, this is the less important point. I can see putting them at function-scope being easy enough and more clearly correct. But I do still wonder about the approach using Variable.T and such, instead of something "custom" involving Cg.declare_local and separate hooks in ProcBody esp. for initialization.<br> <br> <br>(Though I can see a "custom" approach having other benefits: e.g. doing a multiplication jmpbuf_size times number of trys and making one larger call to alloca. Furthermore, the approach that uses just one jmpbuf for the entire function, plus a local integer, would more reasonly need a special access to the function scope.)<br> <br> <br>I have a bit more time to spend here now maybe..but I'm tempted to put in a temporary hack of using a 1K jmpbuf for all targets..at least that keeps the per-target code out... and an assert m3core that it is large enough (as was there already).<br> <br> <br> <br>We could also pick some liberal values per-processor, like 64 bytes for x86, 128 for amd64, 512 for sparc, 1K for powerpc/alpha/mips/other, along with the assertion. (powerpc does tend to need quite large jmpbuf, alpha/mips/other are rare and can suffer until a better solution is in place, 64 for x86 is still bloated but not so bad temporarily..)) Again, this is just a stopgap. The fact that very long running loops with a try allocate more and more stack is quite bad. I didn't realize it at the time, sorry.<br> <br> <br>I also think the frontend should declare the EF1 type correctly and itself, so as to initialize the pointer in it, instead of having a separate pointer local variable that gets copied to it.<br> <br> <br> - Jay<br><br> <br><hr id="stopSpelling">From:<span class="Apple-converted-space"> </span><a href="mailto:jay.krell@cornell.edu">jay.krell@cornell.edu</a><br>To:<span class="Apple-converted-space"> </span><a href="mailto:hosking@cs.purdue.edu">hosking@cs.purdue.edu</a><br>Date: Tue, 1 Feb 2011 07:16:40 +0000<br>CC:<span class="Apple-converted-space"> </span><a href="mailto:m3devel@elegosoft.com">m3devel@elegosoft.com</a><br>Subject: Re: [M3devel] fixing try/setjmp in a loop?<br><br>These look like good hints. I wouldn't know to make such slightly large changes,<br>that the existing infrastructure doesn't suffice.<br>I'll have a go at it..as my now-very-limited time permits.<br><br>Thanks,<br> - Jay<br><br><hr id="ecxstopSpelling">From:<span class="Apple-converted-space"> </span><a href="mailto:hosking@cs.purdue.edu">hosking@cs.purdue.edu</a><br>Date: Mon, 31 Jan 2011 22:45:53 -0500<br>To:<span class="Apple-converted-space"> </span><a href="mailto:jay.krell@cornell.edu">jay.krell@cornell.edu</a><br>CC:<span class="Apple-converted-space"> </span><a href="mailto:m3devel@elegosoft.com">m3devel@elegosoft.com</a><br>Subject: Re: [M3devel] fixing try/setjmp in a loop?<br><br>I'd like to do what you envisage.  It is a significant improvement, and should not require too much effort:<div>1) Use Declare_local and track all marker declarations in Marker.m3 (similar to Tracer.m3)</div><div>2) Have a callback from Procedure.GenBody (right after Scope.InitValues) to a new procedure Marker.EmitPending that emits the declarations and the initialisations of the variables to NIL.</div><div><br><div><div>On Jan 31, 2011, at 7:55 PM, Jay K wrote:</div><br class="ecxApple-interchange-newline"><blockquote><span class="ecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font: normal normal normal medium/normal Helvetica; white-space: normal; letter-spacing: normal; word-spacing: 0px; "><div class="ecxhmmessage" style="font-family: Tahoma; font-size: 10pt; ">ps: I'm happy to report that my available time here<br>has become significantly reduced. Partly with that in mind,<br>but even w/o it, I am willing to go back to the old way.<br>m3front is full of mystery and I'm not sure I'm keen on understanding it.<br> <br> <br> - Jay<br><br> <br><hr id="ecxstopSpelling">From:<span class="ecxApple-converted-space"> </span><a href="mailto:hosking@cs.purdue.edu">hosking@cs.purdue.edu</a><br>Date: Mon, 31 Jan 2011 15:26:20 -0500<br>To:<span class="ecxApple-converted-space"> </span><a href="mailto:jay.krell@cornell.edu">jay.krell@cornell.edu</a><br>CC:<span class="ecxApple-converted-space"> </span><a href="mailto:m3devel@elegosoft.com">m3devel@elegosoft.com</a><br>Subject: Re: [M3devel] fixing try/setjmp in a loop?<br><br>I think we need to have a way to get the scope of the containing procedure.<div>TryStmt.Parse is not the right place.</div><div>If I get some time soon I can take a look at this.<br><br><div><div>On Jan 31, 2011, at 2:19 PM, Jay K wrote:</div><br class="ecxApple-interchange-newline"><blockquote><span class="ecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font: normal normal normal medium/normal Helvetica; white-space: normal; letter-spacing: normal; word-spacing: 0px; "><div class="ecxhmmessage" style="font-family: Tahoma; font-size: 10pt; ">Right..I also tried Scope.Insert, didn't seem to help.<br> <br>But I think I might be doing it too late. I'll try doing it in Parse instead of Check.<br>Though I don't recall if Parse knows enough -- if it knows if CaptureState will be called.<br>I agree/disagree about alloca up front, with the obvious reasons -- it is smaller code to alloca up front, and it somewhat<br>more closely resembles the old pattern:<br> <br>IF Foo() THEN<br>  RETURN<br>ELSE TRY FINALLY<br> <br>in the old way would use the stack, so we could too.<br>But the allocation is slower/larger now (alloca possibly aligning up more than needed).<br>Anyway, this point isn't the problem. The problem is my inability to work with m3front.<br>I'll look at it a bit more -- i.e. as I said, moving the code to Parse.<br> <br>The other improvement I'd like to make:<br> <br>currently, if I had it working, what I'm aiming for is:<br>struct EF1{ ... jmpbuf* jb } ef1;<br>jmpbuf* jb = 0;<br> <br>jb = jb ? jb : alloca(sizeof(*jb));<br>ef1.jb = jb;<br>setjmp(ef1.jb);<br> <br>but it'd be better to have:<br> <br>struct EF1{ ... jmpbuf* jb } ef1;<br>ef1.jb = 0;<br> <br>ef1.jb = ef1.jb ? ef1.jb : alloca(sizeof(*jb));<br>setjmp(ef1.jb);<br> <br> <br>ie. we don't need the extra pointer variable, the pointer in the record should suffice.<br> <br> <br>[not sure where to put this in email]<br>  I tried figuring out how to determine the current vs. topmost-in-current-function scope.<br>  I'm not sure if Scope.Top is about in a function or if it is module scope, or even perhaps<br>  some outside-all-modules scope. But Scope.Insert doesn't let you specify a scope,<br>  so I kinda hoped it'd just use the correct scope.<br> <br> <br>Anyway, I'll look again at introducing the Variable.New and Scope.Insert during Parse.<br>Even if it doesn't get used, that might be ok, since there is tracking of use, and<br>declaring it might not cause any waste if it isn't used.<br> <br> <br>Thanks,<br> - Jay<br><br> <br><hr id="ecxstopSpelling">From:<span class="ecxApple-converted-space"> </span><a href="mailto:hosking@cs.purdue.edu">hosking@cs.purdue.edu</a><br>Date: Mon, 31 Jan 2011 12:14:09 -0500<br>To:<span class="ecxApple-converted-space"> </span><a href="mailto:jay.krell@cornell.edu">jay.krell@cornell.edu</a><br>CC:<span class="ecxApple-converted-space"> </span><a href="mailto:m3devel@elegosoft.com">m3devel@elegosoft.com</a><br>Subject: Re: [M3devel] fixing try/setjmp in a loop?<br><br>Hi Jay,<div><br></div><div>I've not had a chance to digest this, but I do understand the problem.  We need the Variable to be entered into the outermost scope of the procedure in which the TRY appears so that it will have initialization code (assigning NIL) generated for it on entry to the procedure.  Then your usage of the variable should simply check for NIL and alloca if it is, as you already appear to do here.  It would be possible to have the initialization code perform the alloca but then we would have an alloca for every TRY block in a procedure even if they never execute.  Probably not the best plan.</div><div><br><div><span class="ecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font: normal normal normal 12px/normal Helvetica; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px; "><span class="ecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font: normal normal normal 12px/normal Helvetica; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px; "><div style="word-wrap: break-word; "><span class="ecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font: normal normal normal 12px/normal Helvetica; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px; "><span class="ecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font: normal normal normal 12px/normal Helvetica; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px; "><span class="ecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font: normal normal normal 12px/normal Helvetica; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px; "><span class="ecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font: normal normal normal 12px/normal Helvetica; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px; "><span class="ecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font: normal normal normal 12px/normal Helvetica; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px; "><span class="ecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font: normal normal normal 12px/normal Helvetica; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px; "><span class="ecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font: normal normal normal 12px/normal Helvetica; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px; "><span class="ecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font: normal normal normal 12px/normal Helvetica; white-space: normal; letter-spacing: normal; color: rgb(0, 0, 0); word-spacing: 0px; "><div><font class="ecxApple-style-span" color="#0000ff"><font class="ecxApple-style-span" face="Gill Sans"><span class="ecxApple-style-span" style="font-family: 'Gill Sans'; color: rgb(0, 0, 255); "><span class="ecxApple-style-span" style="font-family: 'Gill Sans'; color: rgb(0, 0, 255); ">Antony Hosking</span></span></font></font><font class="ecxApple-style-span" face="Gill Sans"><span class="ecxApple-style-span" style="font-family: 'Gill Sans'; "><span class="ecxApple-style-span" style="font-family: 'Gill Sans'; "><span class="ecxApple-converted-space"> </span>|<span class="ecxApple-converted-space"> </span></span></span><span class="ecxApple-style-span" style="font-family: 'Gill Sans'; "><span class="ecxApple-style-span" style="font-family: 'Gill Sans'; ">Associate Professor</span></span><span class="ecxApple-style-span" style="font-family: 'Gill Sans'; "><span class="ecxApple-style-span" style="font-family: 'Gill Sans'; "> | Computer Science | Purdue University</span></span></font></div><div><font class="ecxApple-style-span" face="GillSans-Light"><span class="ecxApple-style-span" style="font-family: GillSans-Light; ">305 N. University Street | West Lafayette | IN 47907 | USA</span></font></div><div><font class="ecxApple-style-span" color="#0000ff" face="Gill Sans"><span class="ecxApple-style-span" style="font-family: 'Gill Sans'; color: rgb(0, 0, 255); "><span class="ecxApple-style-span" style="font-family: 'Gill Sans'; color: rgb(0, 0, 255); ">Office</span></span></font><font class="ecxApple-style-span" face="GillSans-Light"><span class="ecxApple-style-span" style="font-family: GillSans-Light; "><span class="ecxApple-style-span" style="font-family: GillSans-Light; "> +1 765 494 6001 |<span class="ecxApple-converted-space"> </span></span></span></font><font class="ecxApple-style-span" color="#0000ff" face="Gill Sans"><span class="ecxApple-style-span" style="font-family: 'Gill Sans'; color: rgb(0, 0, 255); "><span class="ecxApple-style-span" style="font-family: 'Gill Sans'; color: rgb(0, 0, 255); ">Mobile</span></span></font><font class="ecxApple-style-span" face="GillSans-Light"><span class="ecxApple-style-span" style="font-family: GillSans-Light; "><span class="ecxApple-style-span" style="font-family: GillSans-Light; "><span class="ecxApple-converted-space"> </span>+1 765 427 5484</span></span></font></div><div><font class="ecxApple-style-span" face="GillSans-Light"><br class="ecxkhtml-block-placeholder"></font></div></span></span></span></span></span></span></span><br class="ecxApple-interchange-newline"></span></div></span></span><br class="ecxApple-interchange-newline"></div><br><div><div>On Jan 30, 2011, at 5:45 AM, Jay K wrote:</div><br class="ecxApple-interchange-newline"><blockquote><span class="ecxApple-style-span" style="text-transform: none; text-indent: 0px; border-collapse: separate; font: normal normal normal medium/normal Helvetica; white-space: normal; letter-spacing: normal; word-spacing: 0px; "><div class="ecxhmmessage" style="font-family: Tahoma; font-size: 10pt; ">I'm trying to fix the inadvertant change I made where<br>FOR i := 1 TO 10 DO TRY FINALLY END<br><br>will call alloca 10 times.<br><br>I'm not familiar with the frontend, and it is hard for me to understand.<br>It seems like it is probably very well factored, written by someone who really knew what they were doing,<br>but it is dense, and not verbosely commented.<br><br>Something like this?? But this doesn't work. What am I missing?<br>And, we should go the next step and merge the jmpbuf pointer variable with the jmpbuf field in the EF1, right?<br><br><br>? 1.txt<br>Index: src/misc/Marker.i3<br>===================================================================<br>RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.i3,v<br>retrieving revision 1.1.1.1<br>diff -u -r1.1.1.1 Marker.i3<br>--- src/misc/Marker.i3    14 Jan 2001 13:40:31 -0000    1.1.1.1<br>+++ src/misc/Marker.i3    30 Jan 2011 10:41:18 -0000<br>@@ -64,9 +64,12 @@<br> PROCEDURE SetLock (acquire: BOOLEAN;  var: CG.Var;  offset: INTEGER);<br> (* generate the call to acquire or release a mutex *)<br> <br>-PROCEDURE CaptureState (frame: CG.Var;  handler: CG.Label);<br>+PROCEDURE CaptureState (frame: CG.Var;  handler: CG.Label;<br>+                        jumpbuf: Variable.T);<br> (* call 'setjmp' on 'frame's jmpbuf and branch to 'handler' on re-returns. *)<br> <br> PROCEDURE Reset ();<br> <br>+PROCEDURE NewJumpbuf (): Variable.T;<br>+<br> END Marker.<br>Index: src/misc/Marker.m3<br>===================================================================<br>RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Marker.m3,v<br>retrieving revision 1.9<br>diff -u -r1.9 Marker.m3<br>--- src/misc/Marker.m3    13 Jan 2011 14:58:28 -0000    1.9<br>+++ src/misc/Marker.m3    30 Jan 2011 10:41:18 -0000<br>@@ -10,7 +10,7 @@<br> MODULE Marker;<br> <br> IMPORT CG, Error, Type, Variable, ProcType, ESet, Expr, AssignStmt;<br>-IMPORT M3ID, M3RT, Target, Module, RunTyme, Procedure, Host;<br>+IMPORT M3ID, M3RT, Target, Module, RunTyme, Procedure, Host, Addr;<br> <br> TYPE<br>   Kind = { zFINALLY, zFINALLYPROC, zLOCK, zEXIT, zTRY, zTRYELSE,<br>@@ -231,8 +231,10 @@<br>     END;<br>   END CallFinallyHandler;<br> <br>-PROCEDURE CaptureState (frame: CG.Var;  handler: CG.Label) =<br>+PROCEDURE CaptureState (frame: CG.Var;  handler: CG.Label;<br>+                        jumpbuf: Variable.T) =<br>   VAR new: BOOLEAN;<br>+      label := CG.Next_label ();<br>   BEGIN<br>     (* int setjmp(void* ); *)<br>     IF (setjmp = NIL) THEN<br>@@ -262,13 +264,33 @@<br>                                         Target.Word.size, Target.Word.align,<br>                                         Target.Word.cg_type, 0);<br>     END;<br>-   <span class="ecxApple-converted-space"> </span><br>-    (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *)<br>+<br>+    (* IF jumpuf # NIL THEN   <span class="ecxApple-converted-space"> </span><br>+     *   frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size);<br>+     * END<br>+     *)<br>+<br>+    CG.Load_nil ();<br>+    Variable.Load (jumpbuf);<br>+    CG.If_compare (CG.Type.Addr, CG.Cmp.NE, label, CG.Maybe);<br>+<br>     CG.Start_call_direct (alloca, 0, Target.Address.cg_type);<br>     CG.Load_int (Target.Word.cg_type, Jumpbuf_size);<br>     CG.Pop_param (Target.Word.cg_type);<br>     CG.Call_direct (alloca, Target.Address.cg_type);<br>+<br>+    (* FUTURE: We should actually have a Variable<br>+     * for the entire EF1, including initializing the jumpbuf<br>+     * in it. That would save us this extra load/store,<br>+     * and save a local variable.<br>+     *)<br>+    Variable.LoadLValue (jumpbuf);<br>+    CG.Swap ();<br>+    CG.Store_indirect (CG.Type.Addr, 0, Target.Address.size);<br>+    Variable.Load (jumpbuf);<br>+<br>     CG.Store_addr (frame, M3RT.EF1_jmpbuf);<br>+    CG.Set_label (label);<br> <br>     (* setmp(frame.jmpbuf) *)<br>     CG.Start_call_direct (setjmp, 0, Target.Integer.cg_type);<br>@@ -806,5 +828,15 @@<br>     tos          := 0;<br>   END Reset;<br> <br>+PROCEDURE NewJumpbuf (): Variable.T =<br>+  VAR jumpbuf: Variable.T;<br>+  BEGIN<br>+   jumpbuf := Variable.New (M3ID.NoID, TRUE);<br>+   Variable.BindType (jumpbuf, Addr.T, indirect := FALSE,<br>+                      readonly := FALSE, open_array_ok := FALSE,<br>+                      needs_init := TRUE);<br>+   RETURN jumpbuf;<br>+  END NewJumpbuf;<br>+<br> BEGIN<br> END Marker.<br>Index: src/stmts/TryFinStmt.m3<br>===================================================================<br>RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryFinStmt.m3,v<br>retrieving revision 1.6<br>diff -u -r1.6 TryFinStmt.m3<br>--- src/stmts/TryFinStmt.m3    5 Jan 2011 14:34:54 -0000    1.6<br>+++ src/stmts/TryFinStmt.m3    30 Jan 2011 10:41:18 -0000<br>@@ -10,6 +10,7 @@<br> <br> IMPORT M3ID, CG, Token, Scanner, Stmt, StmtRep, Marker, Target, Type, Addr;<br> IMPORT RunTyme, Procedure, ProcBody, M3RT, Scope, Fmt, Host, TryStmt, Module;<br>+IMPORT Variable;<br> FROM Stmt IMPORT Outcome;<br> <br> TYPE<br>@@ -20,6 +21,7 @@<br>         viaProc  : BOOLEAN;<br>         scope    : Scope.T;<br>         handler  : HandlerProc;<br>+        jumpbuf  : Variable.T := NIL;<br>       OVERRIDES<br>         check       := Check;<br>         compile     := Compile;<br>@@ -63,6 +65,11 @@<br>     RETURN p;<br>   END Parse;<br> <br>+PROCEDURE UsesSetjmp (p: P): BOOLEAN =<br>+  BEGIN<br>+    RETURN NOT (Target.Has_stack_walker OR p.viaProc);<br>+  END UsesSetjmp;<br>+<br> PROCEDURE Check (p: P;  VAR cs: Stmt.CheckState) =<br>   VAR zz: Scope.T;  oc: Stmt.Outcomes;  name: INTEGER;<br>   BEGIN<br>@@ -95,6 +102,9 @@<br>       END;<br>     END;<br>     TryStmt.PopHandler ();<br>+    IF UsesSetjmp (p) THEN<br>+     p.jumpbuf := Marker.NewJumpbuf ();<br>+    END;<br>   END Check;<br> <br> PROCEDURE HandlerName (uid: INTEGER): TEXT =<br>@@ -106,11 +116,16 @@<br>   END HandlerName;<br> <br> PROCEDURE Compile (p: P): Stmt.Outcomes =<br>+  VAR usesSetjmp := FALSE;<br>+      result: Stmt.Outcomes;<br>   BEGIN<br>-    IF Target.Has_stack_walker THEN RETURN Compile1 (p);<br>-    ELSIF p.viaProc            THEN RETURN Compile2 (p);<br>-    ELSE                            RETURN Compile3 (p);<br>+    IF Target.Has_stack_walker THEN result := Compile1 (p);<br>+    ELSIF p.viaProc            THEN result := Compile2 (p);<br>+    ELSE                            usesSetjmp := TRUE;<br>+                                    result := Compile3 (p);<br>     END;<br>+    <* ASSERT usesSetjmp = UsesSetjmp (p) *><br>+    RETURN result;<br>   END Compile;<br> <br> PROCEDURE Compile1 (p: P): Stmt.Outcomes =<br>@@ -302,7 +317,9 @@<br>     l := CG.Next_label (3);<br>     CG.Set_label (l, barrier := TRUE);<br>     Marker.PushFrame (frame, M3RT.HandlerClass.Finally);<br>-    Marker.CaptureState (frame, l+1);<br>+    <* ASSERT UsesSetjmp (p) *><br>+    <* ASSERT p.jumpbuf # NIL *><br>+    Marker.CaptureState (frame, l+1, p.jumpbuf);<br> <br>     (* compile the body *)<br>     Marker.PushFinally (l, l+1, frame);<br>Index: src/stmts/TryStmt.m3<br>===================================================================<br>RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/TryStmt.m3,v<br>retrieving revision 1.3<br>diff -u -r1.3 TryStmt.m3<br>--- src/stmts/TryStmt.m3    5 Jan 2011 14:34:54 -0000    1.3<br>+++ src/stmts/TryStmt.m3    30 Jan 2011 10:41:18 -0000<br>@@ -22,6 +22,7 @@<br>         hasElse   : BOOLEAN;<br>         elseBody  : Stmt.T;<br>         handled   : ESet.T;<br>+        jumpbuf   : Variable.T := NIL;<br>       OVERRIDES<br>         check       := Check;<br>         compile     := Compile;<br>@@ -153,6 +154,14 @@<br>     p.handles := h3;<br>   END ReverseHandlers;<br> <br>+PROCEDURE UsesSetjmp (p: P): BOOLEAN =<br>+  BEGIN<br>+    IF (p.handles = NIL) AND (NOT p.hasElse) THEN<br>+      RETURN FALSE;<br>+    END;<br>+    RETURN NOT Target.Has_stack_walker;<br>+  END UsesSetjmp;<br>+<br> PROCEDURE Check (p: P;  VAR cs: Stmt.CheckState) =<br>   VAR h: Handler;  handled: ESet.T;<br>   BEGIN<br>@@ -182,6 +191,10 @@<br>       WHILE (h # NIL) DO CheckHandler (h, cs); h := h.next; END;<br>       Stmt.TypeCheck (p.elseBody, cs);<br>     PopHandler ();<br>+<br>+    IF UsesSetjmp (p) THEN<br>+      p.jumpbuf := Marker.NewJumpbuf ();<br>+    END;<br>   END Check;<br> <br> PROCEDURE CheckLabels (h: Handler;  scope: Scope.T;  VAR cs: Stmt.CheckState) =<br>@@ -245,14 +258,19 @@<br>   END CheckHandler;<br> <br> PROCEDURE Compile (p: P): Stmt.Outcomes =<br>+  VAR usesSetjmp := FALSE;<br>+      result: Stmt.Outcomes;<br>   BEGIN<br>     IF (p.handles = NIL) AND (NOT p.hasElse) THEN<br>-      RETURN Stmt.Compile (p.body);<br>-    END;<br>-    IF Target.Has_stack_walker<br>-      THEN RETURN Compile1 (p);<br>-      ELSE RETURN Compile2 (p);<br>+      result := Stmt.Compile (p.body);<br>+    ELSIF Target.Has_stack_walker THEN<br>+      result := Compile1 (p);<br>+    ELSE<br>+      usesSetjmp := TRUE;<br>+      result := Compile2 (p);<br>     END;<br>+    <* ASSERT usesSetjmp = UsesSetjmp (p) *><br>+    RETURN result;<br>   END Compile;<br> <br> PROCEDURE Compile1 (p: P): Stmt.Outcomes =<br>@@ -423,7 +441,9 @@<br>     END;<br> <br>     (* capture the machine state *)<br>-    Marker.CaptureState (frame, l+1);<br>+    <* ASSERT UsesSetjmp (p) *><br>+    <* ASSERT p.jumpbuf # NIL *><br>+    Marker.CaptureState (frame, l+1, p.jumpbuf);<br> <br>     (* compile the body *)<br>     oc := Stmt.Compile (p.body);<br><br>Thanks,<br> - Jay<br></div></span></blockquote></div><br></div></div></span><br class="ecxApple-interchange-newline"></blockquote></div><br></div></div></span><br class="ecxApple-interchange-newline"></blockquote></div><br></div></div></span><br class="Apple-interchange-newline"></blockquote></div><br></div></div></body></html>