[m-rev.] for review: allow inlining of java foreign_procs

Peter Wang novalazy at gmail.com
Thu May 6 13:06:57 AEST 2010


Branches: main, 10.04

Allow inlining of Java foreign_procs.

This revealed a problem with directly using the `succeeded' flag directly as
the success indicator in Java foreign_procs.  When the code of the foreign_proc
becomes a nested function, and after nested functions are eliminated, there may
not be a variable called `succeeded' in that context; it is moved into
environment struct, and the transformation is not able to update handwritten
code to reflect that.  The solution is to declare a local variable for the
foreign_proc, let the handwritten code assign that, then assign its final
value to the `succeeded' flag with an MLDS statement.

We take the opportunity to name the local variable `SUCCESS_INDICATOR', in
line with other backends.

compiler/inlining.m:
        Allow inlining of Java foreign_procs.

compiler/ml_foreign_proc_gen.m:
        In the code generated for semidet Java foreign_procs, declare a local
        `SUCCESS_INDICATOR' variable and assign its value to the `succeeded'
        flag afterwards.

        Add braces to give the foreign_proc variables a limited scope.

doc/reference_manual.texi:
        Update documentation for the renaming of the `succeeded' variable.

library/array.m:
library/bitmap.m:
library/builtin.m:
library/char.m:
library/construct.m:
library/dir.m:
library/exception.m:
library/float.m:
library/int.m:
library/io.m:
library/math.m:
library/private_builtin.m:
library/rtti_implementation.m:
library/string.m:
library/thread.m:
library/time.m:
library/type_desc.m:
library/version_array.m:
        Conform to renaming.

        Fix problems with Java foreign_procs that may now be copied into other
        modules when intermodule optimisation is enabled, some by disallowing
        the procedures from being duplicated, some by making referenced
        classes/fields `public'.

        [Some of the `may_not_duplicate' attributes may not indicate actual
        problems, just that it seems not worthwhile inlining calls to the
        procedure.]

extras/solver_types/library/any_array.m:
tests/hard_coded/equality_pred_which_requires_boxing.m:
tests/hard_coded/external_unification_pred.m:
tests/hard_coded/java_test.m:
tests/hard_coded/redoip_clobber.m:
tests/hard_coded/user_compare.m:
tests/valid/exported_foreign_type2.m:
tests/warnings/warn_succ_ind.m:
        Conform to renaming.

diff --git a/compiler/inlining.m b/compiler/inlining.m
index 7dde958..864dcc7 100644
--- a/compiler/inlining.m
+++ b/compiler/inlining.m
@@ -1020,13 +1020,13 @@ can_inline_proc_2(PredId, ProcId, BuiltinState, HighLevelCode,
 
 ok_to_inline_language(lang_c, target_c).
 ok_to_inline_language(lang_erlang, target_erlang).
+ok_to_inline_language(lang_java, target_java).
 
 % ok_to_inline_language(il, il). %
 % XXX we need to fix the handling of parameter marshalling for inlined code
 % before we can enable this -- see the comments in
 % ml_gen_ordinary_pragma_il_proc in ml_code_gen.m.
 %
-% ok_to_inline_language(java, java). % foreign_language = java not implemented
 % ok_to_inline_language(asm, asm).   % foreign_language = asm not implemented
 % We could define a language "C/C++" (c_slash_cplusplus) which was the
 % intersection of "C" and "C++", and then we'd have
diff --git a/compiler/ml_foreign_proc_gen.m b/compiler/ml_foreign_proc_gen.m
index 2a6f285..e1674b0 100644
--- a/compiler/ml_foreign_proc_gen.m
+++ b/compiler/ml_foreign_proc_gen.m
@@ -341,8 +341,7 @@ ml_gen_ordinary_pragma_foreign_proc(CodeModel, Attributes, PredId, ProcId,
             Foreign_Code, Context, Decls, Statements, !Info)
     ;
         Lang = lang_java,
-        % XXX should pass OrdinaryKind
-        ml_gen_ordinary_pragma_java_proc(CodeModel, Attributes,
+        ml_gen_ordinary_pragma_java_proc(OrdinaryKind, Attributes,
             PredId, ProcId, Args, ExtraArgs,
             Foreign_Code, Context, Decls, Statements, !Info)
     ;
@@ -351,13 +350,13 @@ ml_gen_ordinary_pragma_foreign_proc(CodeModel, Attributes, PredId, ProcId,
             "ml_gen_ordinary_pragma_foreign_proc: unexpected language Erlang")
     ).
 
-:- pred ml_gen_ordinary_pragma_java_proc(code_model::in,
+:- pred ml_gen_ordinary_pragma_java_proc(ordinary_pragma_kind::in,
     pragma_foreign_proc_attributes::in, pred_id::in, proc_id::in,
     list(foreign_arg)::in, list(foreign_arg)::in, string::in,
     prog_context::in, list(mlds_defn)::out, list(statement)::out,
     ml_gen_info::in, ml_gen_info::out) is det.
 
-ml_gen_ordinary_pragma_java_proc(_CodeModel, Attributes, PredId, _ProcId,
+ml_gen_ordinary_pragma_java_proc(OrdinaryKind, Attributes, PredId, _ProcId,
         Args, ExtraArgs, JavaCode, Context, Decls, Statements, !Info) :-
     Lang = get_foreign_language(Attributes),
 
@@ -382,19 +381,58 @@ ml_gen_ordinary_pragma_java_proc(_CodeModel, Attributes, PredId, _ProcId,
     ml_gen_pragma_java_output_arg_list(MutableSpecial, Args, Context,
         AssignOutputsList, ConvDecls, ConvStatements, !Info),
 
-    % Put it all together
-    % XXX FIXME need to handle model_semi code here,
-    % i.e. provide some equivalent to SUCCESS_INDICATOR.
-    Java_Code = list.condense([
+    % Put it all together.
+
+    (
+        OrdinaryKind = kind_det,
+        SucceededDecl = [],
+        AssignSucceeded = []
+    ;
+        OrdinaryKind = kind_semi,
+        ml_success_lval(!.Info, SucceededLval),
+        SucceededDecl = [
+            raw_target_code("\tboolean SUCCESS_INDICATOR;\n", [])],
+        AssignSucceeded = [
+            raw_target_code("\t", []),
+            target_code_output(SucceededLval),
+            raw_target_code(" = SUCCESS_INDICATOR;\n", [])
+        ]
+    ;
+        OrdinaryKind = kind_failure,
+        ml_success_lval(!.Info, SucceededLval),
+        SucceededDecl = [],
+        AssignSucceeded = [
+            raw_target_code("\t", []),
+            target_code_output(SucceededLval),
+            raw_target_code(" = false;\n", [])
+        ]
+    ),
+
+    Starting_Code = list.condense([
+        [raw_target_code("{\n", [])],
         ArgDeclsList,
+        SucceededDecl,
         AssignInputsList,
         [user_target_code(JavaCode, yes(Context), [])]
     ]),
-    Java_Code_Stmt = inline_target_code(ml_target_java, Java_Code),
-    Java_Code_Statement = statement(
-        ml_stmt_atomic(Java_Code_Stmt),
+    Starting_Code_Stmt = inline_target_code(ml_target_java, Starting_Code),
+    Starting_Code_Statement = statement(ml_stmt_atomic(Starting_Code_Stmt),
+        mlds_make_context(Context)),
+
+    Ending_Code = list.condense([
+        AssignSucceeded,
+        [raw_target_code("\t}\n", [])]
+    ]),
+    Ending_Code_Stmt = inline_target_code(ml_target_java, Ending_Code),
+    Ending_Code_Statement = statement(ml_stmt_atomic(Ending_Code_Stmt),
         mlds_make_context(Context)),
-    Statements = [Java_Code_Statement | AssignOutputsList] ++ ConvStatements,
+
+    Statements = list.condense([
+        [Starting_Code_Statement],
+        AssignOutputsList,
+        ConvStatements,
+        [Ending_Code_Statement]
+    ]),
     Decls = ConvDecls.
 
 :- type ordinary_pragma_kind
diff --git a/doc/reference_manual.texi b/doc/reference_manual.texi
index 0cd490a..dde4ca8 100644
--- a/doc/reference_manual.texi
+++ b/doc/reference_manual.texi
@@ -8237,7 +8237,7 @@ for mapping Mercury types to Java types are described in
 The Java code in a @code{pragma foreign_proc} declaration
 for a procedure whose determinism indicates that it can fail
 must assign a value of type @samp{boolean} to the variable
- at samp{succeeded}.  For example:
+ at samp{SUCCESS_INDICATOR}.  For example:
 
 @example
 :- pred string.contains_char(string, character).
@@ -8246,22 +8246,22 @@ must assign a value of type @samp{boolean} to the variable
 :- pragma foreign_proc("Java",
 	string.contains_char(Str::in, Ch::in),
         [will_not_call_mercury, promise_pure],
-        "succeeded = (Str.IndexOf(Ch) != -1);").
+        "SUCCESS_INDICATOR = (Str.IndexOf(Ch) != -1);").
 @end example
 
 @noindent
 Java code for procedures whose determinism indicates that they cannot fail
-should not refer to the @code{succeeded} variable.
+should not refer to the @code{SUCCESS_INDICATOR} variable.
 
 Arguments whose mode is input will have their values set by the
 Mercury implementation on entry to the Java code.
 With our current implementation, the Java code must set the values
 of all output variables, even if the procedure fails
-(i.e. sets the @samp{succeeded} variable to @code{false}).
+(i.e. sets the @samp{SUCCESS_INDICATOR} variable to @code{false}).
 @c If the procedure
 @c succeeds, the Java code must set the values of all output arguments
 @c If the procedure fails, the Java code need only
- at c set the @code{succeeded} variable to false.
+ at c set the @code{SUCCESS_INDICATOR} variable to false.
 
 @node Using pragma foreign_export for Java
 @subsubsection Using pragma foreign_export for Java
diff --git a/extras/solver_types/library/any_array.m b/extras/solver_types/library/any_array.m
index 50bebeb..483f07f 100644
--- a/extras/solver_types/library/any_array.m
+++ b/extras/solver_types/library/any_array.m
@@ -339,7 +339,7 @@
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     // never do bounds checking for Java (throw exceptions instead)
-    succeeded = false;
+    SUCCESS_INDICATOR = false;
 ").
 
 %-----------------------------------------------------------------------------%
diff --git a/library/array.m b/library/array.m
index 19d3a8e..7a75e9a 100644
--- a/library/array.m
+++ b/library/array.m
@@ -596,7 +596,7 @@ array.compare_elements(N, Size, Array1, Array2, Result) :-
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     // never do bounds checking for Java (throw exceptions instead)
-    succeeded = false;
+    SUCCESS_INDICATOR = false;
 ").
 
 :- pragma foreign_proc("Erlang",
@@ -1133,7 +1133,7 @@ ML_resize_array(MR_ArrayPtr array, MR_ArrayPtr old_array,
 
 :- pragma foreign_proc("Java",
     array.resize(Array0::array_di, Size::in, Item::in, Array::array_uo),
-    [will_not_call_mercury, promise_pure, thread_safe],
+    [will_not_call_mercury, promise_pure, thread_safe, may_not_duplicate],
 "
     if (Size == 0) {
         Array = null;
diff --git a/library/bitmap.m b/library/bitmap.m
index 61adab6..1e57c17 100644
--- a/library/bitmap.m
+++ b/library/bitmap.m
@@ -1614,7 +1614,7 @@ public class MercuryBitmap {
     bitmap_equal(BM1::in, BM2::in),
     [will_not_call_mercury, thread_safe, promise_pure, will_not_modify_trail],
 "
-    succeeded = BM1.equals(BM2);
+    SUCCESS_INDICATOR = BM1.equals(BM2);
 ").
 
 :- pragma foreign_proc("Erlang",
diff --git a/library/builtin.m b/library/builtin.m
index 521056f..61a9272 100644
--- a/library/builtin.m
+++ b/library/builtin.m
@@ -947,7 +947,7 @@ special__Compare____tuple_0_0(ref object[] result,
     [may_call_mercury, thread_safe, promise_pure, terminates],
 "
     try {
-        Y = deep_copy(X);
+        Y = builtin.deep_copy(X);
     } catch (java.lang.InstantiationException E) {
         throw new RuntimeException(E);
     } catch (java.lang.IllegalAccessException E) {
@@ -960,7 +960,7 @@ special__Compare____tuple_0_0(ref object[] result,
     [may_call_mercury, thread_safe, promise_pure, terminates],
 "
     try {
-        Y = deep_copy(X);
+        Y = builtin.deep_copy(X);
     } catch (java.lang.InstantiationException E) {
         throw new RuntimeException(E);
     } catch (java.lang.IllegalAccessException E) {
diff --git a/library/char.m b/library/char.m
index 0b7bd01..5771ebf 100644
--- a/library/char.m
+++ b/library/char.m
@@ -555,7 +555,7 @@ char.det_from_int(Int) = Char :-
     char.to_int(Character::in, Int::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    succeeded = ((int) Character == Int);
+    SUCCESS_INDICATOR = ((int) Character == Int);
 ").
 
 :- pragma foreign_proc("Java",
@@ -563,7 +563,7 @@ char.det_from_int(Int) = Char :-
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     Character = (char) Int;
-    succeeded = ((int) Character == Int);
+    SUCCESS_INDICATOR = ((int) Character == Int);
 ").
 
 :- pragma foreign_proc("Erlang",
diff --git a/library/construct.m b/library/construct.m
index fe65efe..672252a 100644
--- a/library/construct.m
+++ b/library/construct.m
@@ -375,7 +375,7 @@ null_to_no(S) = ( if null(S) then no else yes(S) ).
     null(S::in),
     [will_not_call_mercury, thread_safe, promise_pure],
 "
-    succeeded = (S == null);
+    SUCCESS_INDICATOR = (S == null);
 ").
 
 :- pragma foreign_proc("Erlang",
diff --git a/library/dir.m b/library/dir.m
index 8b53d00..3af1280 100644
--- a/library/dir.m
+++ b/library/dir.m
@@ -965,7 +965,8 @@ dir.make_directory(PathName, Result, !IO) :-
 % Java has a similar library function java.io.File.mkdirs()
 :- pragma foreign_proc("Java",
     dir.make_directory(DirName::in, Res::out, _IO0::di, _IO::uo),
-    [may_call_mercury, promise_pure, tabled_for_io, thread_safe, terminates],
+    [may_call_mercury, promise_pure, tabled_for_io, thread_safe, terminates,
+        may_not_duplicate],
 "
     try {
         java.io.File dir = new java.io.File(DirName);
@@ -1031,7 +1032,7 @@ can_implement_make_directory :- semidet_fail.
     can_implement_make_directory,
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    succeeded = true;
+    SUCCESS_INDICATOR = true;
 "
 ).
 :- pragma foreign_proc("Erlang",
@@ -1130,7 +1131,8 @@ dir.make_single_directory(DirName, Result, !IO) :-
 :- pragma foreign_proc("Java",
     dir.make_single_directory_2(ErrorIfExists::in, DirName::in,
         Result::out, _IO0::di, _IO::uo),
-    [may_call_mercury, promise_pure, tabled_for_io, thread_safe, terminates],
+    [may_call_mercury, promise_pure, tabled_for_io, thread_safe, terminates,
+        may_not_duplicate],
 "
     try {
         java.io.File newDir = new java.io.File(DirName);
@@ -1556,7 +1558,7 @@ can_implement_dir_foldl :- semidet_fail.
     can_implement_dir_foldl,
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    succeeded = true;
+    SUCCESS_INDICATOR = true;
 ").
 :- pragma foreign_proc("Erlang",
     can_implement_dir_foldl,
diff --git a/library/exception.m b/library/exception.m
index c0cdb4f..d33cdd0 100644
--- a/library/exception.m
+++ b/library/exception.m
@@ -1667,14 +1667,14 @@ call_handler(Handler, Exception, Result) :- Handler(Exception, Result).
     try {
         jmercury.runtime.Ref<Object> ref =
             new jmercury.runtime.Ref<Object>();
-        succeeded = exception.ML_call_goal_semidet(TypeInfo_for_T,
+        SUCCESS_INDICATOR = exception.ML_call_goal_semidet(TypeInfo_for_T,
             (Object[]) Pred, ref);
         T = ref.val;
     }
     catch (jmercury.runtime.Exception ex) {
         T = exception.ML_call_handler_det(TypeInfo_for_T, (Object[]) Handler,
             (univ.Univ_0) ex.exception);
-        succeeded = true;
+        SUCCESS_INDICATOR = true;
     }
 ").
 :- pragma foreign_proc("Java",
@@ -1702,6 +1702,7 @@ call_handler(Handler, Exception, Result) :- Handler(Exception, Result).
             ""catch_impl (cc_nondet) not yet implemented"");
     }
     T = null;
+    SUCCESS_INDICATOR = false;
 ").
 :- pragma foreign_proc("Java",
     catch_impl(Pred0::pred(out) is multi, Handler0::in(handler), _T::out),
@@ -1720,6 +1721,9 @@ call_handler(Handler, Exception, Result) :- Handler(Exception, Result).
             (univ.Univ_0) ex.exception);
         ((jmercury.runtime.MethodPtr2) cont).call___0_0(T, cont_env_ptr);
     }
+
+    // Not really used.
+    SUCCESS_INDICATOR = false;
 ").
 :- pragma foreign_proc("Java",
     catch_impl(Pred0::pred(out) is nondet, Handler0::in(handler), _T::out),
@@ -1738,6 +1742,9 @@ call_handler(Handler, Exception, Result) :- Handler(Exception, Result).
             (univ.Univ_0) ex.exception);
         ((jmercury.runtime.MethodPtr2) cont).call___0_0(T, cont_env_ptr);
     }
+
+    // Not really used.
+    SUCCESS_INDICATOR = false;
 ").
 
 %-----------------------------------------------------------------------------%
diff --git a/library/float.m b/library/float.m
index ec16028..dfbd4e7 100644
--- a/library/float.m
+++ b/library/float.m
@@ -293,7 +293,7 @@ X / Y = Z :-
 	float_domain_checks,
 	[thread_safe, promise_pure],
 "
-	succeeded = true;
+	SUCCESS_INDICATOR = true;
 ").
 
 :- pragma foreign_proc("Erlang",
@@ -629,7 +629,7 @@ is_nan_or_inf(Float) :-
 	is_nan(Flt::in),
 	[will_not_call_mercury, promise_pure, thread_safe],
 "
-	succeeded = java.lang.Double.isNaN(Flt);
+	SUCCESS_INDICATOR = java.lang.Double.isNaN(Flt);
 ").
 :- pragma foreign_proc("Erlang",
 	is_nan(_Flt::in),
@@ -659,7 +659,7 @@ is_nan_or_inf(Float) :-
 	is_inf(Flt::in),
 	[will_not_call_mercury, promise_pure, thread_safe],
 "
-	succeeded = java.lang.Double.isInfinite(Flt);
+	SUCCESS_INDICATOR = java.lang.Double.isInfinite(Flt);
 ").
 :- pragma foreign_proc("Erlang",
 	is_inf(_Flt::in),
diff --git a/library/int.m b/library/int.m
index 4e59254..12b7c2a 100644
--- a/library/int.m
+++ b/library/int.m
@@ -490,7 +490,7 @@ X rem Y = Rem :-
     int_domain_checks,
     [thread_safe, promise_pure],
 "
-    succeeded = true;
+    SUCCESS_INDICATOR = true;
 ").
 :- pragma foreign_proc("Erlang",
     int_domain_checks,
diff --git a/library/io.m b/library/io.m
index ba381fe..7cf1b80 100644
--- a/library/io.m
+++ b/library/io.m
@@ -1804,9 +1804,9 @@
 
 :- pragma foreign_code("Java",
 "
-    static tree234.Tree234_2<Integer, Stream_info_0> ML_io_stream_db
+    public static tree234.Tree234_2<Integer, Stream_info_0> ML_io_stream_db
         = new tree234.Tree234_2.Empty_0<Integer, Stream_info_0>();
-    static univ.Univ_0 ML_io_user_globals = null;
+    public static univ.Univ_0 ML_io_user_globals = null;
 ").
 
 :- type io.stream_putback ==  map(io.stream_id, list(char)).
@@ -2921,7 +2921,8 @@ io.file_modification_time(File, Result, !IO) :-
 :- pragma foreign_proc("Java",
     io.file_modification_time_2(FileName::in, Status::out, Msg::out,
         Time::out, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+    [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe,
+        may_not_duplicate],
 "
     java.util.Date date = new java.util.Date();
     try {
@@ -3001,7 +3002,7 @@ file_type_implemented :-
     file_type_implemented,
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    succeeded = true;
+    SUCCESS_INDICATOR = true;
 ").
 :- pragma foreign_proc("Erlang",
     file_type_implemented,
@@ -3180,7 +3181,8 @@ file_type_implemented :-
 :- pragma foreign_proc("Java",
     io.file_type_2(_FollowSymLinks::in, FileName::in,
         Result::out, _IO0::di, _IO::uo),
-    [may_call_mercury, promise_pure, tabled_for_io, thread_safe, terminates],
+    [may_call_mercury, promise_pure, tabled_for_io, thread_safe, terminates,
+        may_not_duplicate],
 "
     java.io.File file = new java.io.File(FileName);
 
@@ -5312,14 +5314,14 @@ io.unlock_globals :-
 
 :- pragma foreign_proc("Java",
     io.unsafe_get_globals(Globals::out, _IOState0::di, _IOState::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io],
+    [will_not_call_mercury, promise_pure, tabled_for_io, may_not_duplicate],
 "
     Globals = io.ML_io_user_globals;
 ").
 
 :- pragma foreign_proc("Java",
     io.unsafe_set_globals(Globals::in, _IOState0::di, _IOState::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io],
+    [will_not_call_mercury, promise_pure, tabled_for_io, may_not_duplicate],
 "
     io.ML_io_user_globals = Globals;
 ").
@@ -5375,7 +5377,7 @@ io.progname_base(DefaultName, PrognameBase, !IO) :-
 
 :- pragma foreign_proc("Java",
     io.get_stream_id(Stream::in) = (Id::out),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, may_not_duplicate],
 "
     Id = Stream.id;
 ").
@@ -5764,14 +5766,14 @@ namespace mercury {
         abstract public void close() throws java.io.IOException;
     }
 
-    private static class MR_TextInputFile
+    public static class MR_TextInputFile
         extends MR_MercuryFileStruct
     {
         private java.io.InputStreamReader   input       = null;
         private char[]                      buf         = new char[1024];
         private int                         buf_pos     = 0;
         private int                         buf_end     = 0;
-        private int                         line_number = 1;
+        public  int                         line_number = 1;
 
         public MR_TextInputFile(java.io.InputStream stream) {
             input = new java.io.InputStreamReader(stream);
@@ -5926,7 +5928,7 @@ namespace mercury {
         }
     } // class MR_TextInputFile
 
-    private static class MR_TextOutputFile
+    public static class MR_TextOutputFile
         extends MR_MercuryFileStruct
     {
         private java.io.BufferedWriter  output      = null;
@@ -6003,7 +6005,7 @@ namespace mercury {
         }
     } // class MR_TextOutputFile
 
-    private abstract static class MR_BinaryFile
+    public abstract static class MR_BinaryFile
         extends MR_MercuryFileStruct
     {
         // These must match whence_to_int.
@@ -6062,7 +6064,7 @@ namespace mercury {
         }
     }
 
-    private static class MR_BinaryInputFile
+    public static class MR_BinaryInputFile
         extends MR_BinaryFile
     {
         private java.io.FileInputStream     binary_input = null;
@@ -6119,7 +6121,7 @@ namespace mercury {
         }
     }
 
-    private static class MR_BinaryOutputFile
+    public static class MR_BinaryOutputFile
         extends MR_BinaryFile
     {
         private java.io.FileOutputStream    binary_output = null;
@@ -6403,13 +6405,13 @@ static System.Exception MR_io_exception;
 
 :- pragma foreign_code("Java",
 "
-static MR_TextInputFile mercury_stdin =
+public static MR_TextInputFile mercury_stdin =
     new MR_TextInputFile(java.lang.System.in);
 
-static MR_TextOutputFile mercury_stdout =
+public static MR_TextOutputFile mercury_stdout =
     new MR_TextOutputFile(java.lang.System.out);
 
-static MR_TextOutputFile mercury_stderr =
+public static MR_TextOutputFile mercury_stderr =
     new MR_TextOutputFile(java.lang.System.err);
 
 /**
@@ -6417,18 +6419,18 @@ static MR_TextOutputFile mercury_stderr =
  * only when they are needed,  because the initialization code
  * does not work on Google's App Engine.
  */
-static MR_BinaryInputFile mercury_stdin_binary = null;
+private static MR_BinaryInputFile mercury_stdin_binary = null;
 
-static MR_BinaryOutputFile mercury_stdout_binary = null;
+private static MR_BinaryOutputFile mercury_stdout_binary = null;
 
-static void ensure_init_mercury_stdin_binary() {
+private static void ensure_init_mercury_stdin_binary() {
     if (mercury_stdin_binary == null) {
         mercury_stdin_binary = new MR_BinaryInputFile(
             new java.io.FileInputStream(java.io.FileDescriptor.in));
     }
 }
 
-static void ensure_init_mercury_stdout_binary() {
+private static void ensure_init_mercury_stdout_binary() {
     if (mercury_stdout_binary == null) {
         mercury_stdout_binary = new MR_BinaryOutputFile(
             new java.io.FileOutputStream(java.io.FileDescriptor.out));
@@ -6437,21 +6439,21 @@ static void ensure_init_mercury_stdout_binary() {
 
 // Note: these are also set in io.init_state.
 
-static ThreadLocal<MR_TextInputFile> mercury_current_text_input =
+public static ThreadLocal<MR_TextInputFile> mercury_current_text_input =
     new InheritableThreadLocal<MR_TextInputFile>() {
         protected MR_TextInputFile initialValue() {
             return mercury_stdin;
         }
     };
 
-static ThreadLocal<MR_TextOutputFile> mercury_current_text_output =
+public static ThreadLocal<MR_TextOutputFile> mercury_current_text_output =
     new InheritableThreadLocal<MR_TextOutputFile>() {
         protected MR_TextOutputFile initialValue() {
             return mercury_stdout;
         }
     };
 
-static ThreadLocal<MR_BinaryInputFile> mercury_current_binary_input =
+public static ThreadLocal<MR_BinaryInputFile> mercury_current_binary_input =
     new InheritableThreadLocal<MR_BinaryInputFile>() {
         protected MR_BinaryInputFile initialValue() {
             ensure_init_mercury_stdin_binary();
@@ -6459,7 +6461,7 @@ static ThreadLocal<MR_BinaryInputFile> mercury_current_binary_input =
         }
     };
 
-static ThreadLocal<MR_BinaryOutputFile> mercury_current_binary_output =
+public static ThreadLocal<MR_BinaryOutputFile> mercury_current_binary_output =
     new InheritableThreadLocal<MR_BinaryOutputFile>() {
         protected MR_BinaryOutputFile initialValue() {
             ensure_init_mercury_stdout_binary();
@@ -6467,7 +6469,8 @@ static ThreadLocal<MR_BinaryOutputFile> mercury_current_binary_output =
         }
     };
 
-static ThreadLocal<Exception> MR_io_exception = new ThreadLocal<Exception>();
+public static ThreadLocal<Exception> MR_io_exception =
+    new ThreadLocal<Exception>();
 ").
 
 :- pragma foreign_decl("Erlang", local, "
@@ -7504,7 +7507,7 @@ io.putback_byte(binary_input_stream(Stream), Character, !IO) :-
     [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
 "
     try {
-        ByteVal = ((MR_BinaryInputFile) File).read_byte();
+        ByteVal = ((io.MR_BinaryInputFile) File).read_byte();
     } catch (java.io.IOException e) {
         io.MR_io_exception.set(e);
         ByteVal = -2;
@@ -8178,7 +8181,7 @@ io.flush_binary_output(binary_output_stream(Stream), !IO) :-
 :- pragma foreign_proc("Java",
     io.seek_binary_2(Stream::in, Flag::in, Off::in, _IO0::di, _IO::uo),
     [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe,
-        terminates, may_not_duplicate],
+        terminates],
 "
     try {
         ((io.MR_BinaryFile) Stream).seek_binary(Flag, Off);
@@ -8195,7 +8198,7 @@ io.flush_binary_output(binary_output_stream(Stream), !IO) :-
     try {
         Offset = ((io.MR_BinaryFile) Stream).getOffset();
     } catch (java.io.IOException e) {
-        return -1;
+        Offset = -1;
     }
 ").
 
@@ -8203,56 +8206,56 @@ io.flush_binary_output(binary_output_stream(Stream), !IO) :-
     io.write_string_2(Stream::in, Message::in, _IO0::di, _IO::uo),
     [may_call_mercury, promise_pure, thread_safe, tabled_for_io, terminates],
 "
-    ((MR_TextOutputFile) Stream).write_or_throw(Message);
+    ((io.MR_TextOutputFile) Stream).write_or_throw(Message);
 ").
 
 :- pragma foreign_proc("Java",
     io.write_char_2(Stream::in, Character::in, _IO0::di, _IO::uo),
     [may_call_mercury, promise_pure, thread_safe, tabled_for_io, terminates],
 "
-    ((MR_TextOutputFile) Stream).put_or_throw(Character);
+    ((io.MR_TextOutputFile) Stream).put_or_throw(Character);
 ").
 
 :- pragma foreign_proc("Java",
     io.write_int_2(Stream::in, Val::in, _IO0::di, _IO::uo),
     [may_call_mercury, promise_pure, tabled_for_io, thread_safe, terminates],
 "
-    ((MR_TextOutputFile) Stream).write_or_throw(String.valueOf(Val));
+    ((io.MR_TextOutputFile) Stream).write_or_throw(String.valueOf(Val));
 ").
 
 :- pragma foreign_proc("Java",
     io.write_float_2(Stream::in, Val::in, _IO0::di, _IO::uo),
     [may_call_mercury, promise_pure, tabled_for_io, thread_safe, terminates],
 "
-    ((MR_TextOutputFile) Stream).write_or_throw(String.valueOf(Val));
+    ((io.MR_TextOutputFile) Stream).write_or_throw(String.valueOf(Val));
 ").
 
 :- pragma foreign_proc("Java",
     io.write_byte_2(Stream::in, Byte::in, _IO0::di, _IO::uo),
     [may_call_mercury, promise_pure, thread_safe, tabled_for_io, terminates],
 "
-    ((MR_BinaryOutputFile) Stream).put_or_throw((byte) Byte);
+    ((io.MR_BinaryOutputFile) Stream).put_or_throw((byte) Byte);
 ").
 
 :- pragma foreign_proc("Java",
     io.write_bytes_2(Stream::in, Message::in, _IO0::di, _IO::uo),
     [may_call_mercury, promise_pure, thread_safe, tabled_for_io, terminates],
 "
-    ((MR_BinaryOutputFile) Stream).write_or_throw(Message);
+    ((io.MR_BinaryOutputFile) Stream).write_or_throw(Message);
 ").
 
 :- pragma foreign_proc("Java",
     io.flush_output_2(Stream::in, _IO0::di, _IO::uo),
     [may_call_mercury, promise_pure, thread_safe, tabled_for_io, terminates],
 "
-    ((MR_TextOutputFile) Stream).flush_or_throw();
+    ((io.MR_TextOutputFile) Stream).flush_or_throw();
 ").
 
 :- pragma foreign_proc("Java",
     io.flush_binary_output_2(Stream::in, _IO0::di, _IO::uo),
     [may_call_mercury, promise_pure, thread_safe, tabled_for_io, terminates],
 "
-    ((MR_BinaryOutputFile) Stream).flush_or_throw();
+    ((io.MR_BinaryOutputFile) Stream).flush_or_throw();
 ").
 
 :- pragma foreign_proc("Erlang",
@@ -8905,44 +8908,50 @@ io.set_binary_output_stream(binary_output_stream(NewStream),
 
 :- pragma foreign_proc("Java",
     io.stdin_binary_stream_2(Stream::out, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
+    [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io,
+        may_not_duplicate],
 "
-    ensure_init_mercury_stdin_binary();
+    io.ensure_init_mercury_stdin_binary();
     Stream = io.mercury_stdin_binary;
 ").
 
 :- pragma foreign_proc("Java",
     io.stdout_binary_stream_2(Stream::out, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
+    [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io,
+        may_not_duplicate],
 "
-    ensure_init_mercury_stdout_binary();
+    io.ensure_init_mercury_stdout_binary();
     Stream = io.mercury_stdout_binary;
 ").
 
 :- pragma foreign_proc("Java",
     io.input_stream_2(Stream::out, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io],
+    [will_not_call_mercury, promise_pure, tabled_for_io,
+        may_not_duplicate],
 "
     Stream = io.mercury_current_text_input.get();
 ").
 
 :- pragma foreign_proc("Java",
     io.output_stream_2(Stream::out, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io],
+    [will_not_call_mercury, promise_pure, tabled_for_io,
+        may_not_duplicate],
 "
     Stream = io.mercury_current_text_output.get();
 ").
 
 :- pragma foreign_proc("Java",
     io.binary_input_stream_2(Stream::out, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io],
+    [will_not_call_mercury, promise_pure, tabled_for_io,
+        may_not_duplicate],
 "
     Stream = io.mercury_current_binary_input.get();
 ").
 
 :- pragma foreign_proc("Java",
     io.binary_output_stream_2(Stream::out, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io],
+    [will_not_call_mercury, promise_pure, tabled_for_io,
+        may_not_duplicate],
 "
     Stream = io.mercury_current_binary_output.get();
 ").
@@ -9000,7 +9009,7 @@ io.set_binary_output_stream(binary_output_stream(NewStream),
     io.set_output_line_number_2(Stream::in, LineNum::in, _IO0::di, _IO::uo),
     [will_not_call_mercury, promise_pure, tabled_for_io],
 "
-    ((MR_TextOutputFile) Stream).line_number = LineNum;
+    ((io.MR_TextOutputFile) Stream).line_number = LineNum;
 ").
 
     % io.set_input_stream(NewStream, OldStream, IO0, IO1)
@@ -9448,7 +9457,8 @@ io.close_binary_output(binary_output_stream(Stream), !IO) :-
 
 :- pragma foreign_proc("Java",
     io.close_stream(Stream::in, _IO0::di, _IO::uo),
-    [may_call_mercury, promise_pure, tabled_for_io, thread_safe, terminates],
+    [may_call_mercury, promise_pure, tabled_for_io, thread_safe, terminates,
+        may_not_duplicate],
 "
     try {
         Stream.close();
@@ -9771,21 +9781,24 @@ io.handle_system_command_exit_code(Status0::in) = (Status::out) :-
 
 :- pragma foreign_proc("Java",
     io.progname(_Default::in, PrognameOut::out, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+    [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe,
+        may_not_duplicate],
 "
     PrognameOut = jmercury.runtime.JavaInternal.progname;
 ").
 
 :- pragma foreign_proc("Java",
     io.get_exit_status(ExitStatus::out, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io],
+    [will_not_call_mercury, promise_pure, tabled_for_io,
+        may_not_duplicate],
 "
     ExitStatus = jmercury.runtime.JavaInternal.exit_status;
 ").
 
 :- pragma foreign_proc("Java",
     io.set_exit_status(ExitStatus::in, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io],
+    [will_not_call_mercury, promise_pure, tabled_for_io,
+        may_not_duplicate],
 "
     jmercury.runtime.JavaInternal.exit_status = ExitStatus;
 ").
@@ -9843,16 +9856,16 @@ command_line_argument(_, "") :-
 
 :- pragma foreign_proc("Java",
     command_line_argument(ArgNum::in, Arg::out),
-    [will_not_call_mercury, promise_pure, thread_safe],
+    [will_not_call_mercury, promise_pure, thread_safe, may_not_duplicate],
 "
     String[] arg_vector = jmercury.runtime.JavaInternal.args;
 
     if (ArgNum < arg_vector.length && ArgNum >= 0) {
         Arg = arg_vector[ArgNum];
-        succeeded = true;
+        SUCCESS_INDICATOR = true;
     } else {
         Arg = null;
-        succeeded = false;
+        SUCCESS_INDICATOR = false;
     }
 ").
 
@@ -9951,10 +9964,10 @@ command_line_argument(_, "") :-
 
 :- pragma foreign_proc("Java",
     io.getenv(Var::in, Value::out),
-    [will_not_call_mercury, tabled_for_io],
+    [will_not_call_mercury, tabled_for_io, may_not_duplicate],
 "
     Value = System.getenv(Var);
-    succeeded = (Value != null);
+    SUCCESS_INDICATOR = (Value != null);
 ").
 
 :- pragma foreign_proc("Erlang",
@@ -10004,18 +10017,18 @@ io.setenv(Var, Value) :-
 
 :- pragma foreign_proc("Java",
     io.setenv(Var::in, Value::in),
-    [will_not_call_mercury, tabled_for_io],
+    [will_not_call_mercury, tabled_for_io, may_not_duplicate],
 "
     // Java does not provide a method to set environment variables, only a way
     // to modify the environment when creating a new process.
 
     // Avoid warning: Var, Value
-    succeeded = false;
+    SUCCESS_INDICATOR = false;
 ").
 
 :- pragma foreign_proc("Java",
     io.putenv(VarAndValue::in),
-    [will_not_call_mercury, tabled_for_io],
+    [will_not_call_mercury, tabled_for_io, may_not_duplicate],
 "
     // This procedure should never be called, as io.setenv/2 has been
     // implemented directly for Java.
@@ -10478,7 +10491,8 @@ io.remove_file(FileName, Result, !IO) :-
 :- pragma foreign_proc("Java",
     io.remove_file_2(FileName::in, RetVal::out, RetStr::out,
         _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+    [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe,
+        may_not_duplicate],
 "
     try {
         java.io.File file = new java.io.File(FileName);
@@ -10616,7 +10630,8 @@ io.rename_file(OldFileName, NewFileName, Result, IO0, IO) :-
 :- pragma foreign_proc("Java",
     io.rename_file_2(OldFileName::in, NewFileName::in, RetVal::out,
         RetStr::out, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+    [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe,
+        may_not_duplicate],
 "
     try {
         java.io.File file = new java.io.File(OldFileName);
@@ -10824,7 +10839,8 @@ io.read_symlink(FileName, Result, !IO) :-
 :- pragma foreign_proc("Java",
     io.make_symlink_2(_FileName::in, _LinkFileName::in, _Status::out,
         _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+    [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe,
+        may_not_duplicate],
 "
     if (true) {
         throw new java.lang.RuntimeException(
@@ -10835,7 +10851,8 @@ io.read_symlink(FileName, Result, !IO) :-
 :- pragma foreign_proc("Java",
     io.read_symlink_2(_FileName::in, _TargetFileName::out, _Status::out,
         _Error::out, _IO0::di, _IO::uo),
-    [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+    [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe,
+        may_not_duplicate],
 "
     if (true) {
         throw new java.lang.RuntimeException(
diff --git a/library/math.m b/library/math.m
index 3bc1c32..d40dae2 100644
--- a/library/math.m
+++ b/library/math.m
@@ -287,7 +287,7 @@
     math_domain_checks,
     [thread_safe, promise_pure],
 "
-    succeeded = true;
+    SUCCESS_INDICATOR = true;
 ").
 
 :- pragma foreign_proc("Erlang",
diff --git a/library/private_builtin.m b/library/private_builtin.m
index abf76ea..41973c9 100644
--- a/library/private_builtin.m
+++ b/library/private_builtin.m
@@ -720,7 +720,8 @@ special__Compare____base_typeclass_info_1_0(
         TypeInfo::out),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    TypeInfo = MR_typeclass_info_param_type_info(TypeClassInfo, Index);
+    TypeInfo = jmercury.private_builtin.
+        MR_typeclass_info_param_type_info(TypeClassInfo, Index);
 ").
 
 :- pragma foreign_proc("Java",
@@ -728,7 +729,8 @@ special__Compare____base_typeclass_info_1_0(
         Index::in, TypeInfo::out),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    TypeInfo = MR_typeclass_info_instance_tvar_type_info(TypeClassInfo, Index);
+    TypeInfo = jmercury.private_builtin.
+        MR_typeclass_info_instance_tvar_type_info(TypeClassInfo, Index);
 ").
 
 :- pragma foreign_proc("Java",
@@ -736,7 +738,8 @@ special__Compare____base_typeclass_info_1_0(
         TypeClassInfo::out),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    TypeClassInfo = MR_typeclass_info_superclass_info(TypeClassInfo0, Index);
+    TypeClassInfo = jmercury.private_builtin.
+        MR_typeclass_info_superclass_info(TypeClassInfo0, Index);
 ").
 
 :- pragma foreign_proc("Java",
@@ -744,7 +747,8 @@ special__Compare____base_typeclass_info_1_0(
         Index::in, TypeClassInfo::out),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    TypeClassInfo = MR_typeclass_info_arg_typeclass_info(TypeClassInfo0, Index);
+    TypeClassInfo = jmercury.private_builtin.
+        MR_typeclass_info_arg_typeclass_info(TypeClassInfo0, Index);
 ").
 
 :- pragma foreign_proc("Erlang",
@@ -1910,7 +1914,7 @@ no_clauses(PredName) :-
 :- pragma foreign_proc("Java",
     trace_evaluate_runtime_condition,
     [will_not_call_mercury, thread_safe, promise_semipure,
-        does_not_affect_liveness],
+        does_not_affect_liveness, may_not_duplicate],
 "
     if (true) {
         /* All uses of this predicate should override the body. */
diff --git a/library/rtti_implementation.m b/library/rtti_implementation.m
index 625966c..0743dc6 100644
--- a/library/rtti_implementation.m
+++ b/library/rtti_implementation.m
@@ -209,7 +209,7 @@
 
 :- pragma foreign_code("Java",
 "
-    private static final Type_ctor_rep_0[] static_type_ctor_rep
+    public static final Type_ctor_rep_0[] static_type_ctor_rep
         = new Type_ctor_rep_0[private_builtin.MR_TYPECTOR_REP_MAX];
     static {
         for (int i = 0; i < private_builtin.MR_TYPECTOR_REP_MAX; i++) {
@@ -968,42 +968,42 @@ result_call_9(_::in, (=)::out, _::in, _::in, _::in, _::in, _::in,
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr2 P = (jmercury.runtime.MethodPtr2) Pred;
-    succeeded = (Boolean) P.call___0_0(X, Y);
+    SUCCESS_INDICATOR = (Boolean) P.call___0_0(X, Y);
 ").
 :- pragma foreign_proc("Java",
     semidet_call_4(Pred::in, A::in, X::in, Y::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr3 P = (jmercury.runtime.MethodPtr3) Pred;
-    succeeded = (Boolean) P.call___0_0(A, X, Y);
+    SUCCESS_INDICATOR = (Boolean) P.call___0_0(A, X, Y);
 ").
 :- pragma foreign_proc("Java",
     semidet_call_5(Pred::in, A::in, B::in, X::in, Y::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr4 P = (jmercury.runtime.MethodPtr4) Pred;
-    succeeded = (Boolean) P.call___0_0(A, B, X, Y);
+    SUCCESS_INDICATOR = (Boolean) P.call___0_0(A, B, X, Y);
 ").
 :- pragma foreign_proc("Java",
     semidet_call_6(Pred::in, A::in, B::in, C::in, X::in, Y::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr5 P = (jmercury.runtime.MethodPtr5) Pred;
-    succeeded = (Boolean) P.call___0_0(A, B, C, X, Y);
+    SUCCESS_INDICATOR = (Boolean) P.call___0_0(A, B, C, X, Y);
 ").
 :- pragma foreign_proc("Java",
     semidet_call_7(Pred::in, A::in, B::in, C::in, D::in, X::in, Y::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr6 P = (jmercury.runtime.MethodPtr6) Pred;
-    succeeded = (Boolean) P.call___0_0(A, B, C, D, X, Y);
+    SUCCESS_INDICATOR = (Boolean) P.call___0_0(A, B, C, D, X, Y);
 ").
 :- pragma foreign_proc("Java",
     semidet_call_8(Pred::in, A::in, B::in, C::in, D::in, E::in, X::in, Y::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr7 P = (jmercury.runtime.MethodPtr7) Pred;
-    succeeded = (Boolean) P.call___0_0(A, B, C, D, E, X, Y);
+    SUCCESS_INDICATOR = (Boolean) P.call___0_0(A, B, C, D, E, X, Y);
 ").
 
 :- pragma foreign_proc("Java",
@@ -1275,12 +1275,12 @@ iterate(Start, Max, Func) = Results :-
             }
             ArgPseudoTypeInfos = lst;
         }
-        succeeded = true;
+        SUCCESS_INDICATOR = true;
     } else {
         /* Fail if input is a variable. */
         TypeCtorInfo = null;
         ArgPseudoTypeInfos = null;
-        succeeded = false;
+        SUCCESS_INDICATOR = false;
     }
 ").
 
@@ -1292,7 +1292,8 @@ pseudo_type_ctor_and_args(_, _, _) :-
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     VarNum = PseudoTypeInfo.variable_number;
-    succeeded = (VarNum >= 0 && VarNum <= last_univ_quant_varnum);
+    SUCCESS_INDICATOR =
+        (VarNum >= 0 && VarNum <= rtti_implementation.last_univ_quant_varnum);
 ").
 
 is_univ_pseudo_type_info(_, _) :-
@@ -1303,7 +1304,8 @@ is_univ_pseudo_type_info(_, _) :-
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     VarNum = PseudoTypeInfo.variable_number;
-    succeeded = (VarNum >= first_exist_quant_varnum);
+    SUCCESS_INDICATOR =
+        (VarNum >= rtti_implementation.first_exist_quant_varnum);
 ").
 
 is_exist_pseudo_type_info(_, _) :-
@@ -1695,7 +1697,7 @@ is_exist_pseudo_type_info(_, _) :-
     [will_not_call_mercury, promise_pure, thread_safe, may_not_duplicate],
 "
     Object[] rc = ML_construct(TypeInfo, FunctorNumber, ArgList);
-    succeeded = (Boolean) rc[0];
+    SUCCESS_INDICATOR = (Boolean) rc[0];
     Term = (univ.Univ_0) rc[1];
 ").
 
@@ -2186,7 +2188,7 @@ get_arg(Term, Index, SecTagLocn, FunctorDesc, TypeInfo) = Arg :-
     high_level_data,
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    succeeded = true;
+    SUCCESS_INDICATOR = true;
 ").
 :- pragma foreign_proc("C#",
     high_level_data,
@@ -2248,9 +2250,10 @@ get_arg_type_info_2(TypeInfoParams, TypeInfo, Term, FunctorDesc,
 
 :- pragma foreign_proc("Java",
     type_info_get_higher_order_arity(PseudoTypeInfo::in) = (Arity::out),
-    [will_not_call_mercury, promise_pure, thread_safe, may_not_duplicate],
+    [will_not_call_mercury, promise_pure, thread_safe],
 "
-    TypeInfo_Struct ti = (TypeInfo_Struct) PseudoTypeInfo;
+    jmercury.runtime.TypeInfo_Struct ti =
+        (jmercury.runtime.TypeInfo_Struct) PseudoTypeInfo;
     Arity = ti.args.length;
 ").
 
@@ -2405,7 +2408,7 @@ get_subterm(_, _, _, _, _) = -1 :-
 :- pragma foreign_proc("Java",
     get_subterm(FunctorDesc::in, SubTermTypeInfo::in, Term::in,
         Index::in, ExtraArgs::in) = (Arg::out),
-    [will_not_call_mercury, promise_pure, thread_safe],
+    [will_not_call_mercury, promise_pure, thread_safe, may_not_duplicate],
 "
     // Mention TypeInfo_for_U to avoid a warning.
 
@@ -2506,7 +2509,7 @@ pseudo_type_info_is_variable(_, -1) :-
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     VarNum = TypeInfo.variable_number;
-    succeeded = (VarNum != -1);
+    SUCCESS_INDICATOR = (VarNum != -1);
 
     // Variables number from one, not zero.
     // This is in keeping with mercury_type_info.h.
@@ -2531,8 +2534,8 @@ last_univ_quant_varnum = 512.
 first_exist_quant_varnum = 513.
 
 :- pragma foreign_code("Java", "
-private static final int last_univ_quant_varnum = 512;
-private static final int first_exist_quant_varnum = 513;
+public static final int last_univ_quant_varnum = 512;
+public static final int first_exist_quant_varnum = 513;
 ").
 
 %-----------------------------------------------------------------------------%
@@ -2659,7 +2662,7 @@ same_pointer_value(X, Y) :- same_pointer_value_untyped(X, Y).
     same_pointer_value_untyped(T1::in, T2::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    succeeded = (T1 == T2);
+    SUCCESS_INDICATOR = (T1 == T2);
 ").
 
 same_pointer_value_untyped(_, _) :-
@@ -2938,7 +2941,7 @@ get_type_info_from_term(_, _) = _ :-
 
 :- pragma foreign_proc("Java",
     get_type_info_from_term(Term::in, Index::in) = (TypeInfo::out),
-    [will_not_call_mercury, promise_pure, thread_safe],
+    [will_not_call_mercury, promise_pure, thread_safe, may_not_duplicate],
 "
     if (Term instanceof Object[]) {
         TypeInfo = (jmercury.runtime.TypeInfo_Struct) ((Object[]) Term)[Index];
@@ -2963,7 +2966,7 @@ get_typeclass_info_from_term(_, _) = _ :-
 
 :- pragma foreign_proc("Java",
     get_typeclass_info_from_term(Term::in, Index::in) = (TypeClassInfo::out),
-    [will_not_call_mercury, promise_pure, thread_safe],
+    [will_not_call_mercury, promise_pure, thread_safe, may_not_duplicate],
 "
     if (Term instanceof Object[]) {
         TypeClassInfo = /*typeclass_info*/ (Object[]) ((Object[]) Term)[Index];
@@ -3229,7 +3232,8 @@ type_ctor_compare_pred(_) = unify_or_compare_pred :-
     get_type_ctor_rep(TypeCtorInfo::in) = (TypeCtorRep::out),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    TypeCtorRep = static_type_ctor_rep[TypeCtorInfo.type_ctor_rep.value];
+    TypeCtorRep = rtti_implementation.static_type_ctor_rep[
+        TypeCtorInfo.type_ctor_rep.value];
 ").
 :- pragma foreign_proc("C",
     get_type_ctor_rep(TypeCtorInfo::in) = (TypeCtorRep::out),
@@ -3395,10 +3399,10 @@ type_ctor_num_functors(_) = _ :-
 "
     if (Ordinal >= 0 && Ordinal < TypeCtorInfo.type_ctor_num_functors) {
         FunctorNumber = TypeCtorInfo.type_functor_number_map[Ordinal];
-        succeeded = true;
+        SUCCESS_INDICATOR = true;
     } else {
         FunctorNumber = -1;
-        succeeded = false;
+        SUCCESS_INDICATOR = false;
     }
 ").
 
@@ -3566,7 +3570,7 @@ arg_names_index(_, _) = _ :-
 "
     ArgNames = DuFunctorDesc.du_functor_arg_names;
 
-    succeeded = (ArgNames != null);
+    SUCCESS_INDICATOR = (ArgNames != null);
 ").
 
 :- pred get_du_functor_exist_info(du_functor_desc::in, exist_info::out)
@@ -3582,7 +3586,7 @@ get_du_functor_exist_info(DuFunctorDesc, ExistInfo) :-
 "
     ExistInfo = DuFunctorDesc.du_functor_exist_info;
 
-    succeeded = (ExistInfo != null);
+    SUCCESS_INDICATOR = (ExistInfo != null);
 ").
 
 %-----------------------------------------------------------------------------%
@@ -3762,7 +3766,7 @@ unsafe_make_enum(_) = _ :-
     null(S::in),
     [will_not_call_mercury, thread_safe, promise_pure],
 "
-    succeeded = (S == null);
+    SUCCESS_INDICATOR = (S == null);
 ").
 null(_) :-
     % This version is only used for back-ends for which there is no
diff --git a/library/string.m b/library/string.m
index 5fabd52..2759084 100644
--- a/library/string.m
+++ b/library/string.m
@@ -1467,7 +1467,7 @@ string.from_char_list(Chars::in, Str::uo) :-
         sb.append(c);
     }
     Str = sb.toString();
-    succeeded = true;
+    SUCCESS_INDICATOR = true;
 ").
 
 :- pragma foreign_proc("Erlang",
@@ -1985,7 +1985,7 @@ string.sub_string_search(WholeString, Pattern, Index) :-
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     Index = WholeString.indexOf(Pattern, BeginAt);
-    succeeded = (Index >= 0);
+    SUCCESS_INDICATOR = (Index >= 0);
 ").
 
 :- pragma foreign_proc("Erlang",
@@ -2496,7 +2496,7 @@ make_format(Flags, MaybeWidth, MaybePrec, LengthMod, Spec) =
 :- pragma foreign_proc("Java", using_sprintf,
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    succeeded = false;
+    SUCCESS_INDICATOR = false;
 ").
 :- pragma foreign_proc("Erlang", using_sprintf,
     [will_not_call_mercury, promise_pure, thread_safe],
@@ -3645,14 +3645,14 @@ string.det_to_float(FloatString) =
 
     // leading or trailing whitespace is not allowed
     if (FloatString.length() == 0 || FloatString.trim() != FloatString) {
-        succeeded = false;
+        SUCCESS_INDICATOR = false;
     } else {
         try {
             FloatVal = java.lang.Double.parseDouble(FloatString);
-            succeeded = true;
+            SUCCESS_INDICATOR = true;
         } catch(java.lang.NumberFormatException e) {
             // At this point it *should* in theory be safe just to set
-            // succeeded = false, since the Java API claims that
+            // SUCCESS_INDICATOR = false, since the Java API claims that
             // Double.parseDouble() will handle all the cases we require.
             // However, it turns out that in practice (tested with Sun's
             // Java 2 SDK, Standard Edition, version 1.3.1_04) Java actually
@@ -3661,23 +3661,23 @@ string.det_to_float(FloatString) =
 
             if (FloatString.equalsIgnoreCase(""nan"")) {
                 FloatVal = java.lang.Double.NaN;
-                succeeded = true;
+                SUCCESS_INDICATOR = true;
             } else if (FloatString.equalsIgnoreCase(""infinity"")) {
                 FloatVal = java.lang.Double.POSITIVE_INFINITY;
-                succeeded = true;
+                SUCCESS_INDICATOR = true;
             } else if (FloatString.substring(1).equalsIgnoreCase(""infinity""))
             {
                 if (FloatString.charAt(0) == '+') {
                     FloatVal = java.lang.Double.POSITIVE_INFINITY;
-                    succeeded = true;
+                    SUCCESS_INDICATOR = true;
                 } else if (FloatString.charAt(0) == '-') {
                     FloatVal = java.lang.Double.NEGATIVE_INFINITY;
-                    succeeded = true;
+                    SUCCESS_INDICATOR = true;
                 } else {
-                    succeeded = false;
+                    SUCCESS_INDICATOR = false;
                 }
             } else {
-                succeeded = false;
+                SUCCESS_INDICATOR = false;
             }
         }
     }
@@ -3753,7 +3753,7 @@ count_extra_trailing_zeroes(FloatStr, I, N0) = N :-
     string.contains_char(Str::in, Ch::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    succeeded = (Str.indexOf(Ch) != -1);
+    SUCCESS_INDICATOR = (Str.indexOf(Ch) != -1);
 ").
 
 string.contains_char(String, Char) :-
@@ -3933,12 +3933,12 @@ string.set_char(Char, Index, !Str) :-
 "
     if (Index < 0 || Index >= Str0.length()) {
         Str = null;
-        succeeded = false;
+        SUCCESS_INDICATOR = false;
     } else {
         java.lang.StringBuilder sb = new StringBuilder(Str0);
         sb.setCharAt(Index, Ch);
         Str = sb.toString();
-        succeeded = true;
+        SUCCESS_INDICATOR = true;
     }
 ").
 string.set_char_2(Ch, Index, Str0, Str) :-
@@ -4150,7 +4150,7 @@ string.append(S1::out, S2::out, S3::in) :-
     string.append_iii(S1::in, S2::in, S3::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    succeeded = S3.equals(S1.concat(S2));
+    SUCCESS_INDICATOR = S3.equals(S1.concat(S2));
 ").
 
 :- pragma foreign_proc("Erlang",
@@ -4213,10 +4213,10 @@ string.append_iii(X, Y, Z) :-
 "
     if (S3.startsWith(S1)) {
         S2 = S3.substring(S1.length());
-        succeeded = true;
+        SUCCESS_INDICATOR = true;
     } else {
         S2 = null;
-        succeeded = false;
+        SUCCESS_INDICATOR = false;
     }
 ").
 
@@ -4590,7 +4590,7 @@ string.split(Str, Count, Left, Right) :-
     string.first_char(Str::in, First::in, Rest::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    succeeded = (Str.length() == Rest.length() + 1 &&
+    SUCCESS_INDICATOR = (Str.length() == Rest.length() + 1 &&
         Str.charAt(0) == First &&
         Str.endsWith(Rest));
 ").
@@ -4631,10 +4631,10 @@ string.split(Str, Count, Left, Right) :-
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     if (Str.length() == Rest.length() + 1 && Str.endsWith(Rest)) {
-        succeeded = true;
+        SUCCESS_INDICATOR = true;
         First = Str.charAt(0);
     } else {
-        succeeded = false;
+        SUCCESS_INDICATOR = false;
         // XXX to avoid uninitialized var warning
         First = (char) 0;
     }
@@ -4689,10 +4689,10 @@ string.split(Str, Count, Left, Right) :-
     int len = Str.length();
 
     if (len > 0) {
-        succeeded = (First == Str.charAt(0));
+        SUCCESS_INDICATOR = (First == Str.charAt(0));
         Rest = Str.substring(1);
     } else {
-        succeeded = false;
+        SUCCESS_INDICATOR = false;
         // XXX to avoid uninitialized var warning
         Rest = null;
     }
@@ -4745,14 +4745,14 @@ string.split(Str, Count, Left, Right) :-
     [will_not_call_mercury, promise_pure, thread_safe],
 "{
     if (Str.length() == 0) {
-        succeeded = false;
+        SUCCESS_INDICATOR = false;
         // XXX to avoid uninitialized var warnings:
         First = (char) 0;
         Rest = null;
     } else {
         First = Str.charAt(0);
         Rest = Str.substring(1);
-        succeeded = true;
+        SUCCESS_INDICATOR = true;
     }
 }").
 :- pragma foreign_proc("Erlang",
diff --git a/library/thread.m b/library/thread.m
index 458fa52..68b041a 100644
--- a/library/thread.m
+++ b/library/thread.m
@@ -99,7 +99,7 @@
     can_spawn,
     [will_not_call_mercury, promise_pure],
 "
-    succeeded = true;
+    SUCCESS_INDICATOR = true;
 ").
 
 %-----------------------------------------------------------------------------%
diff --git a/library/time.m b/library/time.m
index fc82b4f..d119e02 100644
--- a/library/time.m
+++ b/library/time.m
@@ -513,7 +513,7 @@ time.time(Result, !IO) :-
     time.time_t_is_invalid(_Val::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    succeeded = false;
+    SUCCESS_INDICATOR = false;
 ").
 :- pragma foreign_proc("Erlang",
     time.time_t_is_invalid(_Val::in),
@@ -623,7 +623,7 @@ time.localtime(time_t(Time)) = TM :-
 :- pragma foreign_proc("Java",
     time.c_localtime(Time::in, Yr::out, Mnt::out, MD::out, Hrs::out,
         Min::out, Sec::out, YD::out, WD::out, N::out),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, may_not_duplicate],
 "
     java.util.GregorianCalendar gc = new java.util.GregorianCalendar();
 
@@ -725,7 +725,7 @@ time.gmtime(time_t(Time)) = TM :-
 :- pragma foreign_proc("Java",
     time.c_gmtime(Time::in, Yr::out, Mnt::out, MD::out, Hrs::out,
         Min::out, Sec::out, YD::out, WD::out, N::out),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, may_not_duplicate],
 "
     java.util.GregorianCalendar gc =
         new java.util.GregorianCalendar(
@@ -848,7 +848,7 @@ time.mktime(TM) = time_t(Time) :-
 :- pragma foreign_proc("Java",
     time.c_mktime(Yr::in, Mnt::in, MD::in, Hrs::in, Min::in, Sec::in,
         _YD::in, _WD::in, N::in, Time::out),
-    [will_not_call_mercury, promise_pure],
+    [will_not_call_mercury, promise_pure, may_not_duplicate],
 "
     java.util.GregorianCalendar gc = new java.util.GregorianCalendar(
         Yr + 1900, Mnt, MD, Hrs, Min, Sec);
diff --git a/library/type_desc.m b/library/type_desc.m
index 4184f7f..6f76fa7 100644
--- a/library/type_desc.m
+++ b/library/type_desc.m
@@ -910,18 +910,18 @@ make_type_ctor_desc_with_arity(_, _, _) :-
 "{
     PseudoTypeInfo[] as = new PseudoTypeInfo[TypeCtorDesc.arity];
 
-    succeeded = true;
+    SUCCESS_INDICATOR = true;
     list.List_1<TypeInfo_Struct> arg_types = ArgTypes;
     for (int i = 0; i < TypeCtorDesc.arity; i++) {
         if (list.is_empty(arg_types)) {
-            succeeded = false;
+            SUCCESS_INDICATOR = false;
             break;
         }
         as[i] = list.det_head(arg_types);
         arg_types = list.det_tail(arg_types);
     }
 
-    if (succeeded) {
+    if (SUCCESS_INDICATOR) {
         TypeDesc = new TypeInfo_Struct();
         TypeDesc.init(TypeCtorDesc, as);
     } else {
diff --git a/library/version_array.m b/library/version_array.m
index e4f644e..8cf37db 100644
--- a/library/version_array.m
+++ b/library/version_array.m
@@ -510,10 +510,10 @@ resize(N, X, VA, resize(VA, N, X)).
 "
     try {
         X = VA.get(I);
-        succeeded = true;
+        SUCCESS_INDICATOR = true;
     } catch (ArrayIndexOutOfBoundsException e) {
         X = null;
-        succeeded = false;
+        SUCCESS_INDICATOR = false;
     }
 ").
 
@@ -535,10 +535,10 @@ resize(N, X, VA, resize(VA, N, X)).
 "
     try {
         VA = VA0.set(I, X);
-        succeeded = true;
+        SUCCESS_INDICATOR = true;
     } catch (ArrayIndexOutOfBoundsException e) {
         VA = null;
-        succeeded = false;
+        SUCCESS_INDICATOR = false;
     }
 ").
 
diff --git a/tests/hard_coded/equality_pred_which_requires_boxing.m b/tests/hard_coded/equality_pred_which_requires_boxing.m
index 1a3c57e..68243ae 100644
--- a/tests/hard_coded/equality_pred_which_requires_boxing.m
+++ b/tests/hard_coded/equality_pred_which_requires_boxing.m
@@ -114,7 +114,7 @@ unify(S, X, Y, !IO) :-
 	SUCCESS_INDICATOR = (X == Y);
 ").
 :- pragma foreign_proc("Java", unify_ft(X::in, Y::in), [promise_pure], "
-	succeeded = X.equals(Y);
+	SUCCESS_INDICATOR = X.equals(Y);
 ").
 :- pragma foreign_proc("Erlang", unify_ft(X::in, Y::in), [promise_pure], "
 	SUCCESS_INDICATOR = (X =:= Y)
@@ -129,7 +129,7 @@ unify(S, X, Y, !IO) :-
 	SUCCESS_INDICATOR = (X == Y);
 ").
 :- pragma foreign_proc("Java", unify_ft_T(X::in, Y::in), [promise_pure], "
-	succeeded = X.equals(Y);
+	SUCCESS_INDICATOR = X.equals(Y);
 ").
 :- pragma foreign_proc("Erlang", unify_ft_T(X::in, Y::in), [promise_pure], "
 	SUCCESS_INDICATOR = (X =:= Y)
diff --git a/tests/hard_coded/external_unification_pred.m b/tests/hard_coded/external_unification_pred.m
index 8816453..4be0c90 100644
--- a/tests/hard_coded/external_unification_pred.m
+++ b/tests/hard_coded/external_unification_pred.m
@@ -37,7 +37,7 @@
     ").
     :- pragma foreign_proc("Java", unify_ft(X::in, Y::in), [promise_pure],
     "
-	    succeeded = (X == Y);
+	    SUCCESS_INDICATOR = (X == Y);
     ").
     :- pragma foreign_proc("Erlang", unify_ft(X::in, Y::in), [promise_pure],
     "
diff --git a/tests/hard_coded/java_test.m b/tests/hard_coded/java_test.m
index 7128200..71ffb12 100644
--- a/tests/hard_coded/java_test.m
+++ b/tests/hard_coded/java_test.m
@@ -64,6 +64,6 @@ XXX `pragma export' not yet supported for Java
 :- pred java_semidet_succeed is semidet.
 :- pred java_semidet_fail is semidet.
 :- pragma foreign_proc("Java", java_semidet_succeed,
-	[will_not_call_mercury, promise_pure], "succeeded = true;").
+	[will_not_call_mercury, promise_pure], "SUCCESS_INDICATOR = true;").
 :- pragma foreign_proc("Java", java_semidet_fail,
-	[will_not_call_mercury, promise_pure], "succeeded = false;").
+	[will_not_call_mercury, promise_pure], "SUCCESS_INDICATOR = false;").
diff --git a/tests/hard_coded/redoip_clobber.m b/tests/hard_coded/redoip_clobber.m
index 31dc7b7..c81f05d 100644
--- a/tests/hard_coded/redoip_clobber.m
+++ b/tests/hard_coded/redoip_clobber.m
@@ -67,7 +67,7 @@ bar(X) :- X = 1.
 :- pragma foreign_proc("Java", use(_X::in),
 	[will_not_call_mercury, promise_pure],
 "
-	succeeded = false;
+	SUCCESS_INDICATOR = false;
 ").
 :- pragma foreign_proc("Erlang", use(_X::in),
 	[will_not_call_mercury, promise_pure],
diff --git a/tests/hard_coded/user_compare.m b/tests/hard_coded/user_compare.m
index dd3b4da..5bade26 100644
--- a/tests/hard_coded/user_compare.m
+++ b/tests/hard_coded/user_compare.m
@@ -71,7 +71,7 @@ compare_foo(Res, Foo1, Foo2) :-
 ).
 :- pragma foreign_proc("Java", foreign_equals(Foreign1::in, Foreign2::in),
                 [will_not_call_mercury, promise_pure],
-"succeeded = (Foreign1 == Foreign2);"
+"SUCCESS_INDICATOR = (Foreign1 == Foreign2);"
 ).
 :- pragma foreign_proc("Erlang", foreign_equals(Foreign1::in, Foreign2::in),
                 [will_not_call_mercury, promise_pure],
diff --git a/tests/valid/exported_foreign_type2.m b/tests/valid/exported_foreign_type2.m
index be49ca5..f5cc398 100644
--- a/tests/valid/exported_foreign_type2.m
+++ b/tests/valid/exported_foreign_type2.m
@@ -16,7 +16,7 @@
 "SUCCESS_INDICATOR = (T1 == T2);").
 
 :- pragma foreign_proc("Java", int_equals(T1::in, T2::in), [promise_pure],
-"succeeded = (T1 == T2);").
+"SUCCESS_INDICATOR = (T1 == T2);").
 
 :- pragma foreign_proc("Erlang", int_equals(T1::in, T2::in), [promise_pure],
 "SUCCESS_INDICATOR = (T1 =:= T2)").
diff --git a/tests/warnings/warn_succ_ind.m b/tests/warnings/warn_succ_ind.m
index f31652a..1036380 100644
--- a/tests/warnings/warn_succ_ind.m
+++ b/tests/warnings/warn_succ_ind.m
@@ -34,7 +34,7 @@
     [will_not_call_mercury, promise_pure],
 "
     X = Y;
-    succeeded = MR_FALSE;
+    SUCCESS_INDICATOR = false;
 ").
 
 :- pragma foreign_proc("Erlang",
@@ -42,7 +42,7 @@
     [will_not_call_mercury, promise_pure],
 "
     X = Y,
-    SUCCESS_INDICATOR = true
+    SUCCESS_INDICATOR = false
 ").
 
 :- pragma foreign_proc("C",
@@ -66,7 +66,7 @@
     [will_not_call_mercury, promise_pure],
 "
     X = Y;
-    succeeded = MR_FALSE;
+    SUCCESS_INDICATOR = false;
 ").
 
 :- pragma foreign_proc("Erlang",
@@ -74,7 +74,7 @@
     [will_not_call_mercury, promise_pure],
 "
     X = Y,
-    SUCCESS_INDICATOR = true
+    SUCCESS_INDICATOR = false
 ").
 
 :- pragma foreign_proc("C",

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