[m-rev.] diff: module initialisers/finalisers for java
Peter Wang
novalazy at gmail.com
Mon Jun 22 13:32:01 AEST 2009
Branches: main
Make `:- initialise' and `:- finalise' declarations work in Java grades.
Initialisation predicates are simply called from static initialisation blocks.
Finalisation predicates work by registering methods (objects) with the
JavaInternal runtime class. After main/2 terminates each of the registered
methods is called.
compiler/make_hlds_passes.m:
Make add_pass_3_initialise, add_pass_3_finalise generate predicates
for backends other than C.
compiler/mlds_to_java.m:
Generate code to register finalisation predicates with the runtime.
Make the generated code that calls main/2 call run the registered
finalisers as well.
java/runtime/JavaInternal.java:
Add code to register and call finalisers when main/2 terminates.
diff --git a/compiler/make_hlds_passes.m b/compiler/make_hlds_passes.m
index fd5a4a0..0da853c 100644
--- a/compiler/make_hlds_passes.m
+++ b/compiler/make_hlds_passes.m
@@ -1338,7 +1338,9 @@ add_pass_3_initialise(ItemInitialise, Status,
!ModuleInfo, !QualInfo,
pred_info_get_arg_types(PredInfo, ArgTypes),
pred_info_get_procedures(PredInfo, ProcTable),
ProcInfos = map.values(ProcTable),
- ExportLang = lang_c,
+ module_info_get_globals(!.ModuleInfo, Globals),
+ globals.get_target(Globals, CompilationTarget),
+ ExportLang = target_lang_to_foreign_export_lang(CompilationTarget),
(
ArgTypes = [Arg1Type, Arg2Type],
type_is_io_state(Arg1Type),
@@ -1502,9 +1504,9 @@ add_pass_3_finalise(ItemFinalise, Status,
!ModuleInfo, !QualInfo, !Specs) :-
pred_info_get_arg_types(PredInfo, ArgTypes),
pred_info_get_procedures(PredInfo, ProcTable),
ProcInfos = map.values(ProcTable),
- % XXX We currently only support finalise declarations for the C
- % and Erlang backends.
- ExportLang = lang_c,
+ module_info_get_globals(!.ModuleInfo, Globals),
+ globals.get_target(Globals, CompilationTarget),
+ ExportLang = target_lang_to_foreign_export_lang(CompilationTarget),
(
ArgTypes = [Arg1Type, Arg2Type],
type_is_io_state(Arg1Type),
@@ -1586,6 +1588,27 @@ add_pass_3_finalise(ItemFinalise, Status,
!ModuleInfo, !QualInfo, !Specs) :-
!:Specs = [Spec | !.Specs]
).
+:- func target_lang_to_foreign_export_lang(compilation_target)
+ = foreign_language.
+
+target_lang_to_foreign_export_lang(CompilationTarget) = ExportLang :-
+ (
+ ( CompilationTarget = target_c
+ ; CompilationTarget = target_asm
+ ; CompilationTarget = target_x86_64
+ ),
+ ExportLang = lang_c
+ ;
+ CompilationTarget = target_erlang,
+ ExportLang = lang_erlang
+ ;
+ CompilationTarget = target_il,
+ ExportLang = lang_il
+ ;
+ CompilationTarget = target_java,
+ ExportLang = lang_java
+ ).
+
:- pred add_pass_3_mutable(item_mutable_info::in,
import_status::in, module_info::in, module_info::out,
qual_info::in, qual_info::out,
diff --git a/compiler/mlds_to_java.m b/compiler/mlds_to_java.m
index 64b5a51..0f67bec 100644
--- a/compiler/mlds_to_java.m
+++ b/compiler/mlds_to_java.m
@@ -315,7 +315,7 @@ output_import(Import, !IO) :-
output_java_src_file(ModuleInfo, Indent, MLDS, !IO) :-
% Run further transformations on the MLDS.
MLDS = mlds(ModuleName, AllForeignCode, Imports, Defns0,
- InitPreds, _FinalPreds, ExportedEnums),
+ InitPreds, FinalPreds, ExportedEnums),
% Do NOT enforce the outermost "mercury" qualifier here. This module
% name is compared with other module names in the MLDS, to avoid
@@ -364,6 +364,8 @@ output_java_src_file(ModuleInfo, Indent, MLDS, !IO) :-
output_exported_enums(Indent + 1, ModuleInfo, ExportedEnums, !IO),
io.write_string("\n// InitPreds\n", !IO),
output_inits(Indent + 1, ModuleInfo, InitPreds, !IO),
+ io.write_string("\n// FinalPreds\n", !IO),
+ output_finals(Indent + 1, ModuleInfo, FinalPreds, !IO),
io.write_string("\n// EnvVarNames\n", !IO),
output_env_vars(Indent + 1, NonRttiDefns, !IO),
output_src_end(Indent, ModuleName, !IO).
@@ -1034,6 +1036,46 @@ output_init_2(Indent, InitPred, !IO) :-
%-----------------------------------------------------------------------------%
%
+% Code to output module finalisers.
+%
+
+:- pred output_finals(indent::in, module_info::in, list(string)::in,
+ io::di, io::uo) is det.
+
+output_finals(Indent, _ModuleInfo, FinalPreds, !IO) :-
+ (
+ FinalPreds = []
+ ;
+ FinalPreds = [_ | _],
+ indent_line(Indent, !IO),
+ io.write_string("static {\n", !IO),
+ indent_line(Indent + 1, !IO),
+ io.write_string("jmercury.runtime.JavaInternal.register_finaliser(\n",
+ !IO),
+ indent_line(Indent + 2, !IO),
+ io.write_string("new java.lang.Runnable() {\n", !IO),
+ indent_line(Indent + 3, !IO),
+ io.write_string("public void run() {\n", !IO),
+ list.foldl(output_final_pred_call(Indent + 4), FinalPreds, !IO),
+ indent_line(Indent + 3, !IO),
+ io.write_string("}\n", !IO),
+ indent_line(Indent + 2, !IO),
+ io.write_string("}\n", !IO),
+ indent_line(Indent + 1, !IO),
+ io.write_string(");\n", !IO),
+ indent_line(Indent, !IO),
+ io.write_string("}\n", !IO)
+ ).
+
+:- pred output_final_pred_call(indent::in, string::in, io::di, io::uo) is det.
+
+output_final_pred_call(Indent, FinalPred, !IO) :-
+ indent_line(Indent, !IO),
+ io.write_string(FinalPred, !IO),
+ io.write_string("();\n", !IO).
+
+%-----------------------------------------------------------------------------%
+%
% Code to output globals for environment variables.
%
@@ -1138,6 +1180,9 @@ maybe_write_main_driver(Indent, ClassName, Defns, !IO) :-
io.write_string(ClassName, !IO),
io.write_string(".main_2_p_0();\n", !IO),
indent_line(Indent + 1, !IO),
+ io.write_string("jmercury.runtime.JavaInternal.run_finalisers();\n",
+ !IO),
+ indent_line(Indent + 1, !IO),
io.write_string("java.lang.System.exit", !IO),
io.write_string("(jmercury.runtime.JavaInternal.exit_status);", !IO),
io.nl(!IO),
diff --git a/java/runtime/JavaInternal.java b/java/runtime/JavaInternal.java
index 9c4aa1e..8434290 100644
--- a/java/runtime/JavaInternal.java
+++ b/java/runtime/JavaInternal.java
@@ -1,5 +1,5 @@
//
-// Copyright (C) 2001-2003 The University of Melbourne.
+// Copyright (C) 2001-2003, 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.
//
@@ -20,4 +20,17 @@ public class JavaInternal {
public static java.lang.String progname;
public static java.lang.String[] args;
public static int exit_status;
+
+ private static java.util.List<Runnable> finalisers
+ = new java.util.ArrayList();
+
+ public static void register_finaliser(Runnable hook) {
+ finalisers.add(hook);
+ }
+
+ public static void run_finalisers() {
+ for (Runnable r : finalisers) {
+ r.run();
+ }
+ }
}
--------------------------------------------------------------------------
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