[m-rev.] diff: mmc --make on java grade

Peter Wang novalazy at gmail.com
Wed Feb 3 12:22:14 AEDT 2010


Branches: main

These changes allow `mmc --make' to work when built in the Java grade.

compiler/make.util.m:
        Implement `get_real_milliseconds' for Java.

compiler/mercury_compile.m:
        Report an error message if "mmc --arg-file" is called with extra
        arguments, instead failing and reporting an non-obvious error message.

library/dir.m:
        Allow `dir.foldl' to work in Java.

library/io.m:
        Make `io.call_system' on Java run the command through "/bin/sh -c", to
        mimic the behaviour on C backends (only if /bin/sh exists).

diff --git a/compiler/make.util.m b/compiler/make.util.m
index c0c9b0f..161bd41 100644
--- a/compiler/make.util.m
+++ b/compiler/make.util.m
@@ -1805,6 +1805,15 @@ make_write_module_or_linked_target(Globals, ModuleName - FileType, !IO) :-
     IO = IO0;
 ").
 
+:- pragma foreign_proc("Java",
+    get_real_milliseconds(Time::out, IO0::di, IO::uo),
+    [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+    // The loss of precision is acceptable for mmc --make.
+    Time = (int) System.currentTimeMillis();
+    IO = IO0;
+").
+
 %-----------------------------------------------------------------------------%
 %
 % Hash functions
diff --git a/compiler/mercury_compile.m b/compiler/mercury_compile.m
index 7013d3e..36f238e 100644
--- a/compiler/mercury_compile.m
+++ b/compiler/mercury_compile.m
@@ -201,13 +201,23 @@ expand_file_into_arg_list(S, Res, !IO) :-
 real_main_after_expansion(CmdLineArgs, !IO) :-
     % XXX Processing the options up to three times is not what you call
     % elegant.
-    ( CmdLineArgs = ["--arg-file", ArgFile] ->
+    ( CmdLineArgs = ["--arg-file", ArgFile | ExtraArgs] ->
         % All the configuration and options file options are passed in the
         % given file, which is created by the parent `mmc --make' process.
         % (make.module_target does this to overcome limits on the lengths
         % of command lines on Windows.) The environment is ignored, unlike
         % with @file syntax.
 
+        % Diagnose bad invocations, e.g. shell redirection operators treated
+        % as command line arguments.
+        (
+            ExtraArgs = []
+        ;
+            ExtraArgs = [_ | _],
+            unexpected(this_file, "extra arguments with --arg-file: " ++
+                string(ExtraArgs))
+        ),
+
         % `mmc --mmake' does not use the --arg-file mechanism for linking.
         Link = no,
 
diff --git a/library/dir.m b/library/dir.m
index 2c7d5a5..08c1ba4 100644
--- a/library/dir.m
+++ b/library/dir.m
@@ -1549,13 +1549,21 @@ can_implement_dir_foldl :- semidet_fail.
 :- pragma foreign_proc("C#",
     can_implement_dir_foldl,
     [will_not_call_mercury, promise_pure, thread_safe],
-    "SUCCESS_INDICATOR = true;"
-).
+"
+    SUCCESS_INDICATOR = true;
+").
+:- pragma foreign_proc("Java",
+    can_implement_dir_foldl,
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    succeeded = true;
+").
 :- pragma foreign_proc("Erlang",
     can_implement_dir_foldl,
     [will_not_call_mercury, promise_pure, thread_safe],
-    "SUCCESS_INDICATOR = true"
-).
+"
+    SUCCESS_INDICATOR = true
+").
 
     % Win32 doesn't allow us to open a directory without
     % returning the first item.
diff --git a/library/io.m b/library/io.m
index cecfd0c..ed510a2 100644
--- a/library/io.m
+++ b/library/io.m
@@ -9851,11 +9851,32 @@ command_line_argument(_, "") :-
 :- pragma foreign_proc("Java",
     io.call_system_code(Command::in, Status::out, Msg::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],
 "
+    boolean has_sh;
     try {
-        java.lang.Process process = java.lang.Runtime.getRuntime().
-            exec(Command);
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkExec(""/bin/sh"");
+            has_sh = true;
+        } else {
+            // If there is no security manager installed we just check if the
+            // file exists.
+            has_sh = new java.io.File(""/bin/sh"").exists();
+        }
+    } catch (java.lang.Exception e) {
+        has_sh = false;
+    }
+
+    try {
+        // Emulate system() if /bin/sh is available.
+        java.lang.Process process;
+        if (has_sh) {
+            final String[] args = {""/bin/sh"", ""-c"", Command};
+            process = java.lang.Runtime.getRuntime().exec(args);
+        } else {
+            process = java.lang.Runtime.getRuntime().exec(Command);
+        }
 
         StreamPipe stdin = new StreamPipe(mercury_stdin,
             process.getOutputStream());

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