<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Tahoma
}
--></style>
</head>
<body class='hmmessage'>
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>-    <br>-    (* frame.jmpbuf = alloca(Csetjmp__Jumpbuf_size); *)<br>+<br>+    (* IF jumpuf # NIL THEN    <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>                                       </body>
</html>