[m-rev.] diff: cleanup after nondet if-then-else (erlang)

Peter Wang wangp at students.csse.unimelb.edu.au
Fri Jul 20 15:12:15 AEST 2007


Estimated hours taken: 0.5
Branches: main

Change the Erlang code that we generate for an if-then-else with a model_non
condition.  If the condition succeeds, we record that in the process
dictionary (like setting a temporary variable) and erase it from the process
dictionary at the end of the if-then-else.  However, we didn't do the clean
up if the if-then-else was exitted by an exception.  Now we wrap the code of
the if-then-else in a `try' statement and always do the cleanup.

compiler/elds.m:
	Change the ELDS to allow try expressions with an optional `catch'
	pattern and an optional `after' expression (for cleaning up).

compiler/erl_code_gen.m:
	Change the generated code as described above

compiler/elds_to_erlang.m:
compiler/erl_code_util.m:
	Conform to the change in the ELDS.

Index: compiler/elds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/elds.m,v
retrieving revision 1.15
diff -u -r1.15 elds.m
--- compiler/elds.m	12 Jul 2007 01:28:42 -0000	1.15
+++ compiler/elds.m	20 Jul 2007 04:55:30 -0000
@@ -187,7 +187,8 @@
     ;       elds_try(
                 try_expr    :: elds_expr,
                 try_cases   :: list(elds_case),
-                try_catch   :: elds_catch
+                try_catch   :: maybe(elds_catch),
+                try_after   :: maybe(elds_expr)
             )
 
             % throw(Expr)
Index: compiler/elds_to_erlang.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/elds_to_erlang.m,v
retrieving revision 1.24
diff -u -r1.24 elds_to_erlang.m
--- compiler/elds_to_erlang.m	12 Jul 2007 01:28:42 -0000	1.24
+++ compiler/elds_to_erlang.m	20 Jul 2007 04:55:33 -0000
@@ -579,7 +579,7 @@
         nl_indent_line(Indent, !IO),
         io.write_string("end)", !IO)
     ;
-        Expr = elds_try(ExprA, Cases, Catch),
+        Expr = elds_try(ExprA, Cases, MaybeCatch, MaybeAfter),
         io.write_string("(try", !IO),
         nl_indent_line(Indent + 1, !IO),
         output_block_expr(ModuleInfo, VarSet, Indent + 1, ExprA, !IO),
@@ -592,10 +592,24 @@
             io.write_list(Cases, ";",
                 output_case(ModuleInfo, VarSet, Indent + 1), !IO)
         ),
-        nl_indent_line(Indent, !IO),
-        io.write_string("catch", !IO),
-        nl_indent_line(Indent + 1, !IO),
-        output_catch(ModuleInfo, VarSet, Indent + 1, Catch, !IO),
+        (
+            MaybeCatch = yes(Catch),
+            nl_indent_line(Indent, !IO),
+            io.write_string("catch", !IO),
+            nl_indent_line(Indent + 1, !IO),
+            output_catch(ModuleInfo, VarSet, Indent + 1, Catch, !IO)
+        ;
+            MaybeCatch = no
+        ),
+        (
+            MaybeAfter = yes(After),
+            nl_indent_line(Indent, !IO),
+            io.write_string("after", !IO),
+            nl_indent_line(Indent + 1, !IO),
+            output_expr(ModuleInfo, VarSet, Indent + 1, After, !IO)
+        ;
+            MaybeAfter = no
+        ),
         nl_indent_line(Indent, !IO),
         io.write_string("end)", !IO)
     ;
Index: compiler/erl_code_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/erl_code_gen.m,v
retrieving revision 1.21
diff -u -r1.21 erl_code_gen.m
--- compiler/erl_code_gen.m	12 Jul 2007 03:04:15 -0000	1.21
+++ compiler/erl_code_gen.m	20 Jul 2007 04:55:33 -0000
@@ -531,7 +531,7 @@
             erl_gen_commit_pieces(Goal, InstMap, Context, no,
                 GoalStatement, PackedNonLocals, !Info),
 
-            Statement = elds_try(GoalStatement, [AnyCase], Catch),
+            Statement = elds_try(GoalStatement, [AnyCase], yes(Catch), no),
             AnyCase = elds_case(elds_anon_var, elds_term(elds_fail)),
             Catch = elds_catch(elds_throw_atom,
                 elds_tuple([elds_commit_marker, PackedNonLocals]),
@@ -562,7 +562,7 @@
         ResultsVarExpr = expr_from_var(ResultsVar),
 
         Statement = elds_eq(PackedNonLocals, TryExpr),
-        TryExpr = elds_try(GoalStatement, [], Catch),
+        TryExpr = elds_try(GoalStatement, [], yes(Catch), no),
         Catch = elds_catch(elds_throw_atom,
             elds_tuple([elds_commit_marker, ResultsVarExpr]), ResultsVarExpr)
     ;
@@ -1092,15 +1092,15 @@
         %       let PutAndThen = ``put(Ref, true), <Then && SUCCEED()>''
         %
         %       Ref = make_ref(),       /* defaults to `undefined' */
-        %       <Cond && PutAndThen>
-        %       case get(Ref) of
-        %           true -> true ;
-        %           _    -> <Else>
-        %       end,
-        %       erase(Ref)
-        %
-        %   XXX need to ensure the erase(Ref) is done even if an exception is
-        %   thrown (e.g. by commit) by wrapping this with `try'
+        %       try
+        %           <Cond && PutAndThen>
+        %           case get(Ref) of
+        %               true -> true ;
+        %               _    -> <Else>
+        %           end,
+        %       after
+        %           erase(Ref)
+        %       end
         %
 
         erl_gen_info_new_named_var("Ref", Ref, !Info),
@@ -1131,8 +1131,8 @@
         TrueCase = elds_case(elds_true, elds_term(elds_true)),
         OtherCase = elds_case(elds_anon_var, ElseStatement),
 
-        Statement = list.foldr(join_exprs,
-            [MakeRef, CondThen, CaseElse], EraseRef)
+        Statement = join_exprs(MakeRef,
+            elds_try(join_exprs(CondThen, CaseElse), [], no, yes(EraseRef)))
     ).
 
 %-----------------------------------------------------------------------------%
Index: compiler/erl_code_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/erl_code_util.m,v
retrieving revision 1.8
diff -u -r1.8 erl_code_util.m
--- compiler/erl_code_util.m	14 Jun 2007 03:52:48 -0000	1.8
+++ compiler/erl_code_util.m	20 Jul 2007 04:55:33 -0000
@@ -467,11 +467,26 @@
         erl_rename_vars_in_cases(Subn, Cases0, Cases),
         Expr = elds_case_expr(ExprA, Cases)
     ;
-        Expr0 = elds_try(ExprA0, Cases0, Catch0),
+        Expr0 = elds_try(ExprA0, Cases0, MaybeCatch0, MaybeAfter0),
         erl_rename_vars_in_expr(Subn, ExprA0, ExprA),
         erl_rename_vars_in_cases(Subn, Cases0, Cases),
-        erl_rename_vars_in_catch(Subn, Catch0, Catch),
-        Expr = elds_try(ExprA, Cases, Catch)
+        (
+            MaybeCatch0 = yes(Catch0),
+            erl_rename_vars_in_catch(Subn, Catch0, Catch),
+            MaybeCatch = yes(Catch)
+        ;
+            MaybeCatch0 = no,
+            MaybeCatch = no
+        ),
+        (
+            MaybeAfter0 = yes(After0),
+            erl_rename_vars_in_expr(Subn, After0, After),
+            MaybeAfter = yes(After)
+        ;
+            MaybeAfter0 = no,
+            MaybeAfter = no
+        ),
+        Expr = elds_try(ExprA, Cases, MaybeCatch, MaybeAfter)
     ;
         Expr0 = elds_throw(ExprA0),
         erl_rename_vars_in_expr(Subn, ExprA0, ExprA),
@@ -624,10 +639,21 @@
         erl_vars_in_expr(ExprA, !Set),
         erl_vars_in_cases(Cases, !Set)
     ;
-        Expr = elds_try(ExprA, Cases, Catch),
+        Expr = elds_try(ExprA, Cases, MaybeCatch, MaybeAfter),
         erl_vars_in_expr(ExprA, !Set),
         erl_vars_in_cases(Cases, !Set),
-        erl_vars_in_catch(Catch, !Set)
+        (
+            MaybeCatch = yes(Catch),
+            erl_vars_in_catch(Catch, !Set)
+        ;
+            MaybeCatch = no
+        ),
+        (
+            MaybeAfter = yes(After),
+            erl_vars_in_expr(After, !Set)
+        ;
+            MaybeAfter = no
+        )
     ;
         Expr = elds_throw(ExprA),
         erl_vars_in_expr(ExprA, !Set)
@@ -748,11 +774,24 @@
         Expr = elds_case_expr(ExprA, Cases),
         Size = 1 + erl_expr_size(ExprA) + erl_cases_size(Cases)
     ;
-        Expr = elds_try(ExprA, Cases, Catch),
-        Catch = elds_catch(TermA, TermB, CatchExpr),
+        Expr = elds_try(ExprA, Cases, MaybeCatch, MaybeAfter),
+        (
+            MaybeCatch = yes(elds_catch(TermA, TermB, CatchExpr)),
+            CatchSize = erl_term_size(TermA) + erl_term_size(TermB) +
+                erl_expr_size(CatchExpr)
+        ;
+            MaybeCatch = no,
+            CatchSize = 0
+        ),
+        (
+            MaybeAfter = yes(AfterExpr),
+            AfterSize = erl_expr_size(AfterExpr)
+        ;
+            MaybeAfter = no,
+            AfterSize = 0
+        ),
         Size = 1 + erl_expr_size(ExprA) + erl_cases_size(Cases) +
-            erl_term_size(TermA) + erl_term_size(TermB) +
-            erl_expr_size(CatchExpr)
+            CatchSize + AfterSize
     ;
         Expr = elds_throw(ExprA),
         Size = 1 + erl_expr_size(ExprA)
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list