<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>