[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