[m-rev.] for review: refactor mlds_to_il.m

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Jul 11 21:09:44 AEST 2001


On 11-Jul-2001, Tyson Dowd <trd at cs.mu.OZ.AU> wrote:
> 
> I certainly didn't understand it -- as far as I can see the only
> documentation on how to use try/catch for commits is:
> 
> %       model_non in semi context: (using catch/throw)
> %               <succeeded = Goal>
> %       ===>
> %               void success() {
> %                       throw COMMIT;
> %               }
> %               try {
> %                       <Goal && success()>
> %                       succeeded = FALSE;
> %               } catch (COMMIT) {
> %                       succeeded = TRUE;
> %               }

That's the documentation I'm referring to, yes.

> The documentation doesn't say what COMMIT is and I assumed it must be Ref.

Ah, I see.

The paper I've been writing does make it a bit clearer (see below).
(Of course I only wrote that in May, whereas the relevant part of
mlds_to_il.m was written before that...)

 | 	4.6.4  throw/catch
 | 
 | 	When using C++-style exception handling, the `COMMIT_TYPE' local variable
 | 	is not needed, `DO_COMMIT(...)' is a `throw', and `TRY_COMMIT(...)' is a
 | 	`catch':                                                         
 | 	__________________________________________________________________
 | 	|  model_non in semi context (using catch/throw) :                |
 | 	|                                                                 |
 | 	|     < succeeded = once(Goal) >                                  |
 | 	|                                                                 |
 | 	|   =>                                                            |
 | 	|                                                                 |
 | 	|     void success() {                                            |
 | 	|         throw COMMIT();                                         |
 | 	|                                                                 |
 | 	|     }                                                           |
 | 	|                                                                 |
 | 	|     try {                                                       |
 | 	|                                                                 |
 | 	|         < Goal  && success() >                                  |
 | 	|                                                                 |
 | 	|         succeeded = FALSE;                                      |
 | 	|     } catch (COMMIT) {                                          |
 | 	|                                                                 |
 | 	|         succeeded = TRUE;                                       |
 | 	|                                                                 |
 | 	|     }                                                           |
 | 	|_________________________________________________________________|
 | 	__________________________________________________________________|
 | 	|                                                                 |
 | 	|  model_non in det context (using catch/throw) :                 |
 | 	|     < do once(Goal) >                                           |
 | 	|                                                                 |
 | 	|   =>                                                            |
 | 	|                                                                 |
 | 	|     void success() {                                            |
 | 	|                                                                 |
 | 	|         throw COMMIT();                                         |
 | 	|                                                                 |
 | 	|     }                                                           |
 | 	|     try {                                                       |
 | 	|                                                                 |
 | 	|         < Goal  && success() >                                  |
 | 	|                                                                 |
 | 	|     } catch (COMMIT) {}                                         |
 | 	|_________________________________________________________________|
 | 
 | 	Here COMMIT is an exception type, which can be defined trivially
 | 	(e.g. `class COMMIT {}').

The key additions here are the first and last sentence,
and the parentheses after `throw COMMIT'.
I'll copy these changes back to ml_code_gen.m.

> There is also no documentation explaining what Ref is (except that it
> has type mlds__commit type).

There's quite a bit of documentation on the role of Ref in mlds.m.
It says that "Ref" is the name of a local variable of type mlds__commit_type, and
that mlds__commit_type is "The type used for storing information about a commit.
This may be `jmp_buf' or `__label__'."

It doesn't say what mlds__commit_type is in more detail because that depends on
the back-end.  It is just an abstract type that stores information about a commit.

Furthermore, there's also lots of documentation on the role of Ref
in the documentation for the try_commit and do_commit instructions:

                % try_commit(Ref, GoalToTry, CommitHandlerGoal):
                %       Execute GoalToTry.  If GoalToTry exits via a
                %       `commit(Ref)' instruction, then execute
                %       CommitHandlerGoal.
                %
                % do_commit(Ref):
                %       Unwind the stack to the corresponding `try_commit'
                %       statement for Ref, and branch to the CommitHandlerGoal
                %       that was specified in that try_commit instruction.
                %
                % For both try_commit and commit instructions,
                % Ref should be the name of a local variable of type
                % mlds__commit_type.  There should be exactly
                % one try_commit instruction for each Ref.
                % do_commit(Ref) instructions should only be used
                % in goals called from the GoalToTry goal in the
                % try_commit instruction with the same Ref.

The information stored is the mlds__commit_type is just the information needed
to execute the do_commit instruction, i.e. to unwind the stack to the
corresponding try_commit.

So I'm not sure that there's really much I can add.

> > The Ref argument is supposed to hold information about where to resume
> > execution, but for the .NET port the exception handling mechanism
> > takes care of that.  So there's really no need to use the Ref argument
> > at all.
> 
> It would be REALLY NICE if this information was somewhere
> like mlds.m or ml_code_gen.m.

How about the following?

----------

compiler/mlds.m:
compiler/ml_code_gen.m:
	Improve the comments about commit handling.

Workspace: /home/hg/fjh/mercury
Index: compiler/ml_code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_gen.m,v
retrieving revision 1.89
diff -u -d -r1.89 ml_code_gen.m
--- compiler/ml_code_gen.m	2001/06/22 09:14:30	1.89
+++ compiler/ml_code_gen.m	2001/07/11 11:08:23
@@ -158,7 +158,9 @@
 % using the `try_commit' and `do_commit' instructions.
 % The comments below show the MLDS try_commit/do_commit version first,
 % but for clarity I've also included sample code using each of the three
-% different techniques.
+% different techniques.  This shows how the MLDS->target back-end can map
+% mlds__commit_type, do_commit and try_commit into target language
+% constructs.
 %
 % Note that if we're using GCC's __builtin_longjmp(),
 % then it is important that the call to __builtin_longjmp() be
@@ -197,7 +199,7 @@
 %		<succeeded = Goal>
 % 	===>
 %		void success() {
-%			throw COMMIT;
+%			throw COMMIT();
 %		}
 %		try {
 %			<Goal && success()>
@@ -206,14 +208,20 @@
 %			succeeded = TRUE;
 %		}
 
+%	The above is using C++ syntax. Here COMMIT is an exception type,
+%	which can be defined trivially (e.g. "class COMMIT {};").
+%	Note that when using catch/throw, we don't need the "ref" argument
+%	at all; the target language's exception handling implementation
+%	keeps track of all the information needed to unwind the stack.
+
 %	model_non in semi context: (using setjmp/longjmp)
 %		<succeeded = Goal>
 % 	===>
-%		jmp_buf buf;
+%		jmp_buf ref;
 %		void success() {
-%			longjmp(buf, 1);
+%			longjmp(ref, 1);
 %		}
-%		if (setjmp(buf)) {
+%		if (setjmp(ref)) {
 %			succeeded = TRUE;
 %		} else {
 %			<Goal && success()>
@@ -266,7 +274,7 @@
 %		<do Goal>
 %	===>
 %		void success() {
-%			throw COMMIT;
+%			throw COMMIT();
 %		}
 %		try {
 %			<Goal && success()>
@@ -275,11 +283,11 @@
 %	model_non in det context (using setjmp/longjmp):
 %		<do Goal>
 % 	===>
-%		jmp_buf buf;
+%		jmp_buf ref;
 %		void success() {
-%			longjmp(buf, 1);
+%			longjmp(ref, 1);
 %		}
-%		if (setjmp(buf) == 0) {
+%		if (setjmp(ref) == 0) {
 %			<Goal && success()>
 %		}
 
Index: compiler/mlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds.m,v
retrieving revision 1.56
diff -u -d -r1.56 mlds.m
--- compiler/mlds.m	2001/06/22 09:14:35	1.56
+++ compiler/mlds.m	2001/07/11 10:58:17
@@ -510,8 +510,29 @@
 		% to handle nondeterminism
 	;	mlds__cont_type(mlds__return_types)
 
-		% The type used for storing information about a commit.
-		% This may be `jmp_buf' or `__label__'.
+		% mlds__commit_type is used for storing information about a commit.
+		% This is an abstract type; the exact definition will depend
+		% on the back-end.  The only operations on this ADT are
+		% `try_commit' and `do_commit'.  This type holds information
+		% about the `try_commit' stack frame that is needed to unwind
+		% the stack when a `do_commit' is executed.
+		%
+		% For the C back-end, if we're implementing do_commit/try_commit
+		% using setjmp/longmp, then mlds__commit_type will be jmp_buf.
+		% If we're implementing them using GNU C nested functions, then
+		% it will be `__label__'; in this case, the local variable
+		% of this "type" is actually a label, and doing a goto to that
+		% label will unwind the stack.
+		%
+		% If the back-end implements commits using the target language's,
+		% try/catch-style exception handling, as in Java/C++/etc.,
+		% then the target language implementation's exception handling
+		% support will keep track of the information need to unwind
+		% the stack, and so variables of this type don't need
+		% to be declared at all.
+		%
+		% See also the comments in ml_code_gen.m which show how commits
+		% can be implemented for different target languages.
 	;	mlds__commit_type
 
 		% MLDS native builtin types.
@@ -812,9 +833,12 @@
 		%	statement for Ref, and branch to the CommitHandlerGoal
 		%	that was specified in that try_commit instruction.
 		%
-		% For both try_commit and commit instructions,
+		% For both try_commit and do_commit instructions,
 		% Ref should be the name of a local variable of type
-		% mlds__commit_type.  There should be exactly
+		% mlds__commit_type.  (This variable can be used by
+		% the back-end's implementation of do_commit and
+		% try_commit to store information needed to unwind
+		% the stack.)  There should be exactly
 		% one try_commit instruction for each Ref.
 		% do_commit(Ref) instructions should only be used
 		% in goals called from the GoalToTry goal in the

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list