[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