[m-rev.] for review: getMessage for Mercury exceptions in java grade

Peter Wang novalazy at gmail.com
Mon Aug 3 13:15:28 AEST 2009


Branches: main

Make the Java jmercury.runtime.Exception class implement the getMessage()
method for Throwable objects.  This is useful when Mercury code is called
from Java code, without the main/2 wrapper.

java/runtime/Exception.java:
        Add a method pointer as a class variable.

        Implement the getMessage() method by calling the method pointer
        if set.

library/exception.m:
        On module initialisation set the method pointer in the
        jmercury.runtime.Exception class.

        Factor out code from report_uncaught_exception_2.

diff --git a/java/runtime/Exception.java b/java/runtime/Exception.java
index 51943d4..765db2b 100644
--- a/java/runtime/Exception.java
+++ b/java/runtime/Exception.java
@@ -7,11 +7,24 @@
 package jmercury.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.
+    // This is to be set when the exception module is initialised, to avoid
+    // having the runtime depend on the standard library.
+    public static MethodPtr getMessageHook = null;
+
+    // Should be univ.Univ_0 but we don't want to depend on the standard
+    // library.
     public Object exception;
 
     public Exception(Object exception) {
         this.exception = exception;
     }
+
+    public String getMessage() {
+        if (getMessageHook != null) {
+            Object[] args = new Object[] { exception };
+            return (String) getMessageHook.call___0_0(args);
+        } else {
+            return null;
+        }
+    }
 }
diff --git a/library/exception.m b/library/exception.m
index ca93e04..6afb777 100644
--- a/library/exception.m
+++ b/library/exception.m
@@ -2788,14 +2788,43 @@ report_uncaught_exception_2(Exception, unit, !IO) :-
     io.flush_output(!IO),
     io.stderr_stream(StdErr, !IO),
     io.write_string(StdErr, "Uncaught Mercury exception:\n", !IO),
-    ( univ_to_type(Exception, software_error(Message)) ->
-        io.format(StdErr, "Software Error: %s\n", [s(Message)], !IO)
-    ;
-        io.write(StdErr, univ_value(Exception), !IO),
-        io.nl(StdErr, !IO)
-    ),
+    io.write_string(StdErr, exception_to_string(Exception), !IO),
+    io.nl(StdErr, !IO),
     io.flush_output(StdErr, !IO).
 
+:- func exception_to_string(univ) = string.
+
+:- pragma foreign_export("Java", exception_to_string(in) = out,
+    "ML_exception_to_string").
+
+exception_to_string(Exception) = Message :-
+    ( univ_to_type(Exception, software_error(MessagePrime)) ->
+        Message = "Software Error: " ++ MessagePrime
+    ;
+        Message = string(univ_value(Exception))
+    ).
+
+:- initialise(set_get_message_hook/2).
+
+:- pred set_get_message_hook(io::di, io::uo) is det.
+
+set_get_message_hook(!IO).
+
+:- pragma foreign_proc("Java",
+    set_get_message_hook(IO0::di, IO::uo),
+    [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io,
+        may_not_duplicate],
+"
+    jmercury.runtime.Exception.getMessageHook =
+        new jmercury.runtime.MethodPtr() {
+            public java.lang.Object call___0_0(java.lang.Object[] args) {
+                univ.Univ_0 univ = (univ.Univ_0) args[0];
+                return ML_exception_to_string(univ);
+            }
+        };
+    IO = IO0;
+").
+
 %-----------------------------------------------------------------------------%
 
 :- pragma no_inline(throw_if_near_stack_limits/0).

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