[m-rev.] diff: exception handling for java backend

Peter Wang novalazy at gmail.com
Thu May 7 17:06:12 AEST 2009


Branches: main

library/exception.m:
        Implement exception handling predicates for Java.

java/runtime/Exception.java:
        Add a helper class.

diff --git a/java/runtime/Exception.java b/java/runtime/Exception.java
new file mode 100644
index 0000000..52d3084
--- /dev/null
+++ b/java/runtime/Exception.java
@@ -0,0 +1,17 @@
+//
+// Copyright (C) 2009 The University of Melbourne.
+// This file may only be copied under the terms of the GNU Library General
+// Public License - see the file COPYING.LIB in the Mercury distribution.
+//
+
+package mercury.runtime;
+
+public class Exception extends java.lang.Error {
+    // Should be mercury.univ.Univ_0 but we don't want to depend on the
+    // standard library.
+    public Object exception;
+
+    public Exception(Object exception) {
+        this.exception = exception;
+    }
+}
diff --git a/library/exception.m b/library/exception.m
index 99250ef..a6372e1 100644
--- a/library/exception.m
+++ b/library/exception.m
@@ -1614,10 +1614,14 @@ call_handler(Handler, Exception, Result) :-
Handler(Exception, Result).
     "ML_call_goal_det").
 :- pragma foreign_export("IL", call_goal(pred(out) is det, out),
     "ML_call_goal_det").
+:- pragma foreign_export("Java", call_goal(pred(out) is det, out),
+    "ML_call_goal_det").
 :- pragma foreign_export("C", call_goal(pred(out) is semidet, out),
     "ML_call_goal_semidet").
 :- pragma foreign_export("IL", call_goal(pred(out) is semidet, out),
     "ML_call_goal_semidet").
+:- pragma foreign_export("Java", call_goal(pred(out) is semidet, out),
+    "ML_call_goal_semidet").

 % This causes problems because the LLDS back-end
 % does not let you export code with determinism `nondet'.
@@ -1634,72 +1638,107 @@ call_handler(Handler, Exception, Result) :-
Handler(Exception, Result).
     "ML_call_handler_det").
 :- pragma foreign_export("IL", call_handler(pred(in, out) is det, in, out),
     "ML_call_handler_det").
+:- pragma foreign_export("Java", call_handler(pred(in, out) is det, in, out),
+    "ML_call_handler_det").

 :- pragma foreign_proc("Java",
-    throw_impl(_T::in),
+    throw_impl(T::in),
     [will_not_call_mercury, promise_pure],
 "
-    throw new java.lang.Error(""throw_impl not yet implemented"");
+    throw new mercury.runtime.Exception(T);
 ").

 :- pragma foreign_proc("Java",
-    catch_impl(_Pred::pred(out) is det, _Handler::in(handler), _T::out),
+    catch_impl(Pred::pred(out) is det, Handler::in(handler), T::out),
     [will_not_call_mercury, promise_pure],
-"{
-    // the shenanigans with `if (always)' are to avoid errors from
-    // the Java compiler about unreachable code.
-    boolean always = true;
-    if (always) {
-        throw new java.lang.Error(""catch_impl not yet implemented"");
+"
+    try {
+        T = mercury.exception.ML_call_goal_det(
+            (TypeInfo_Struct) TypeInfo_for_T, (Object[]) Pred);
+    }
+    catch (mercury.runtime.Exception ex) {
+        T = mercury.exception.ML_call_handler_det(
+            (TypeInfo_Struct) TypeInfo_for_T, (Object[]) Handler,
+            (mercury.univ.Univ_0) ex.exception);
     }
-}").
+").
 :- pragma foreign_proc("Java",
-    catch_impl(_Pred::pred(out) is semidet, _Handler::in(handler), T::out),
+    catch_impl(Pred::pred(out) is semidet, Handler::in(handler), T::out),
     [will_not_call_mercury, promise_pure],
-"{
-    // the shenanigans with `if (always)' are to avoid errors from
-    // the Java compiler about unreachable code.
-    boolean always = true;
-    if (always) {
-        throw new java.lang.Error(""catch_impl not yet implemented"");
+"
+    try {
+        T = mercury.exception.ML_call_goal_semidet(
+            (TypeInfo_Struct) TypeInfo_for_T, (Object[]) Pred);
     }
-    T = null;
-}").
+    catch (mercury.runtime.Exception ex) {
+        T = mercury.exception.ML_call_handler_det(
+            (TypeInfo_Struct) TypeInfo_for_T, (Object[]) Handler,
+            (mercury.univ.Univ_0) ex.exception);
+    }
+").
 :- pragma foreign_proc("Java",
-    catch_impl(_Pred::pred(out) is cc_multi, _Handler::in(handler), T::out),
+    catch_impl(Pred::pred(out) is cc_multi, Handler::in(handler), T::out),
     [will_not_call_mercury, promise_pure],
-"{
-    // the shenanigans with `if (always)' are to avoid errors from
-    // the Java compiler about unreachable code.
-    boolean always = true;
-    if (always) {
-        throw new java.lang.Error(""catch_impl not yet implemented"");
+"
+    try {
+        T = mercury.exception.ML_call_goal_det(
+            (TypeInfo_Struct) TypeInfo_for_T, (Object[]) Pred);
     }
-    T = null;
-}").
+    catch (mercury.runtime.Exception ex) {
+        T = mercury.exception.ML_call_handler_det(
+            (TypeInfo_Struct) TypeInfo_for_T, (Object[]) Handler,
+            (mercury.univ.Univ_0) ex.exception);
+    }
+").
 :- pragma foreign_proc("Java",
     catch_impl(_Pred::pred(out) is cc_nondet, _Handler::in(handler), T::out),
     [will_not_call_mercury, promise_pure],
-"{
-    // the shenanigans with `if (always)' are to avoid errors from
+"
+    // This predicate isn't called anywhere.
+    // The shenanigans with `if (always)' are to avoid errors from
     // the Java compiler about unreachable code.
     boolean always = true;
     if (always) {
-        throw new java.lang.Error(""catch_impl not yet implemented"");
+        throw new java.lang.Error(
+            ""catch_impl (cc_nondet) not yet implemented"");
     }
     T = null;
-}").
+").
 :- pragma foreign_proc("Java",
-    catch_impl(_Pred::pred(out) is multi, _Handler::in(handler), _T::out),
+    catch_impl(Pred0::pred(out) is multi, Handler0::in(handler), _T::out),
     [will_not_call_mercury, promise_pure, ordinary_despite_detism],
 "
-    throw new java.lang.Error(""catch_impl not yet implemented"");
+    Object[] Pred = (Object[]) Pred0;
+    Object[] Handler = (Object[]) Handler0;
+
+    try {
+        mercury.runtime.MethodPtr pred = (mercury.runtime.MethodPtr) Pred[1];
+        pred.call___0_0(new java.lang.Object[] { Pred, cont, cont_env_ptr });
+    }
+    catch (mercury.runtime.Exception ex) {
+        Object T = mercury.exception.ML_call_handler_det(
+            (TypeInfo_Struct) TypeInfo_for_T, Handler,
+            (mercury.univ.Univ_0) ex.exception);
+        cont.call___0_0(new java.lang.Object[] { T, cont_env_ptr });
+    }
 ").
 :- pragma foreign_proc("Java",
-    catch_impl(_Pred::pred(out) is nondet, _Handler::in(handler), _T::out),
+    catch_impl(Pred0::pred(out) is nondet, Handler0::in(handler), _T::out),
     [will_not_call_mercury, promise_pure, ordinary_despite_detism],
 "
-    throw new java.lang.Error(""catch_impl not yet implemented"");
+    Object[] Pred = (Object[]) Pred0;
+    Object[] Handler = (Object[]) Handler0;
+
+    try {
+        mercury.runtime.MethodPtr pred = (mercury.runtime.MethodPtr) Pred[1];
+        pred.call___0_0(new java.lang.Object[] { Pred, cont, cont_env_ptr });
+    }
+    catch (mercury.runtime.Exception ex) {
+        Object T = mercury.exception.ML_call_handler_det(
+            (TypeInfo_Struct) TypeInfo_for_T, Handler,
+            (mercury.univ.Univ_0) ex.exception);
+        cont.call___0_0(new java.lang.Object[] { T, cont_env_ptr });
+    }
 ").

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