[m-rev.] for prelim review: pragma foreign_import_module on IL backend.

Peter Ross pro at missioncriticalit.com
Fri Dec 6 02:58:30 AEDT 2002


Hi,

This is just for preliminary review as I am going away for a long
weekend.  The log message was written very quickly, so please excuse
if it not comprehensible enough.

Anyway Simon could you cast your eye over this and let me know what
you think and anything that I have missed.


===================================================================


Estimated hours taken: 8
Branches: main

Get pragma foreign_import_module working on the IL backend.

compiler/foreign.m:
	Add two utility predicates which return the module_name
	which a foreign_import refers to.

compiler/ml_code_gen.m:
	A piece of managed C++ code can refer to something defined in
	IL code, so the foreign_imports must be those for the set
	of all the backend languages.

compiler/mlds_to_managed.m:
	Output a #using for each module implied by the pragma
	foreign_import_modules.

compiler/modules.m:
	Add the dependencies that the pragma foreign_import_module
	imply.
	Add to CSHARP_ASSEMBLY_REFS all the modules implied by the
	pragma foreign_import_modules.
	
compiler/prog_io_pragma.m:
	Accept any language in pragma foreign_import_module.

Index: compiler/foreign.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/foreign.m,v
retrieving revision 1.22
diff -u -r1.22 foreign.m
--- compiler/foreign.m	5 Aug 2002 21:46:09 -0000	1.22
+++ compiler/foreign.m	5 Dec 2002 15:45:45 -0000
@@ -89,6 +89,26 @@
 :- func foreign__to_type_string(foreign_language, exported_type) = string.
 :- func foreign__to_type_string(foreign_language, module_info, (type)) = string.
 
+	%
+	% foreign__module_name(ForeignImport)
+	%
+	% returns the module name which represents the ForeignImport.
+	%
+	% For instance for the foreign_import_module representing
+	% 	:- foreign_import_module("MC++", module)
+	% would return the module_name
+	% 	unqualified("module__cpp_code")
+	%
+:- func foreign__module_name(foreign_import_module) = module_name.
+
+	% foreign__module_name(ForeignImport, CurrentModule)
+	%
+	% returns the module name needed to refer to ForeignImport from the
+	% CurrentModule.
+	%
+:- func foreign__module_name(foreign_import_module, module_name) =
+		module_name.
+
 	% Filter the decls for the given foreign language. 
 	% The first return value is the list of matches, the second is
 	% the list of mis-matches.
@@ -201,6 +221,7 @@
 :- import_module check_hlds__mode_util, hlds__error_util.
 :- import_module hlds__hlds_data, parse_tree__prog_out.
 :- import_module backend_libs__code_model, libs__globals.
+:- import_module parse_tree__modules.
 
 	% Currently we don't use the globals to compare foreign language
 	% interfaces, but if we added appropriate options we might want
@@ -685,6 +706,48 @@
 	).
 to_type_string(il, mercury(_Type)) = _ :-
 	sorry(this_file, "to_type_string for il").
+
+%-----------------------------------------------------------------------------%
+
+foreign__module_name(foreign_import_module(Lang, ForeignImportModule, _)) =
+		ModuleName :-
+	( Lang = c,
+		ModuleName = ForeignImportModule
+	; Lang = il,
+		ModuleName = ForeignImportModule
+	; Lang = managed_cplusplus,
+		ModuleName = foreign_language_module_name(ForeignImportModule,
+				Lang)
+	; Lang = csharp,
+		ModuleName = foreign_language_module_name(ForeignImportModule,
+				Lang)
+	).
+
+foreign__module_name(ForeignImportModule, CurrentModule) =
+		ModuleName :-
+	ForeignImportModule = foreign_import_module(Lang, _, _),
+	ModuleName1 = ForeignImportModule ^ foreign__module_name,
+	( Lang = c,
+		ModuleName = ModuleName1
+	; Lang = il,
+		ModuleName = handle_std_library(CurrentModule, ModuleName1)
+	; Lang = managed_cplusplus,
+		ModuleName = handle_std_library(CurrentModule, ModuleName1)
+	; Lang = csharp,
+		ModuleName = handle_std_library(CurrentModule, ModuleName1)
+	).
+
+:- func handle_std_library(module_name, module_name) = module_name.
+
+handle_std_library(CurrentModule, ModuleName0) = ModuleName :-
+	(
+		mercury_std_library_module_name(ModuleName0),
+		\+ mercury_std_library_module_name(CurrentModule)
+	->
+		ModuleName = unqualified("mercury")
+	;
+		ModuleName = ModuleName0
+	).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/ml_code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_gen.m,v
retrieving revision 1.121
diff -u -r1.121 ml_code_gen.m
--- compiler/ml_code_gen.m	14 Jul 2002 04:08:26 -0000	1.121
+++ compiler/ml_code_gen.m	5 Dec 2002 15:45:46 -0000
@@ -817,14 +817,16 @@
 	{ module_info_get_foreign_import_module(ModuleInfo, ForeignImports) },
 	{ module_info_get_foreign_body_code(ModuleInfo, ForeignBodys) },
 	globals__io_get_backend_foreign_languages(BackendForeignLanguages),
-	
+
+	{ WantedForeignImports = list__condense(
+		list__map((func(L) = Imports :-
+			foreign__filter_imports(L, ForeignImports, Imports, _)
+		), BackendForeignLanguages)) },
+
 	{ list__foldl((pred(Lang::in, Map0::in, Map::out) is det :-
 			foreign__filter_decls(Lang,
 				ForeignDecls, WantedForeignDecls, 
 				_OtherForeignDecls),
-			foreign__filter_imports(Lang,
-				ForeignImports, WantedForeignImports, 
-				_OtherForeignImports),
 			foreign__filter_bodys(Lang,
 				ForeignBodys, WantedForeignBodys,
 				_OtherForeignBodys),
Index: compiler/mlds_to_managed.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_managed.m,v
retrieving revision 1.5
diff -u -r1.5 mlds_to_managed.m
--- compiler/mlds_to_managed.m	28 Nov 2002 13:05:20 -0000	1.5
+++ compiler/mlds_to_managed.m	5 Dec 2002 15:45:47 -0000
@@ -89,7 +89,6 @@
 :- mode generate_code(in(managed_lang), in, di, uo) is det.
 
 generate_code(Lang, MLDS) -->
-
 	{ MLDS = mlds(ModuleName, AllForeignCode, Imports, Defns) },
 	{ ClassName = class_name(mercury_module_name_to_mlds(ModuleName), 
 			wrapper_class_name) },
@@ -102,8 +101,7 @@
 
 		% Get the foreign code for the required language.
 	{ ForeignCode = map__lookup(AllForeignCode, Lang) },
-	generate_foreign_header_code(Lang,
-			mercury_module_name_to_mlds(ModuleName), ForeignCode),
+	generate_foreign_header_code(Lang, ModuleName, ForeignCode),
 
 		% Output the namespace.
 	{ generate_namespace_details(Lang, ClassName,
@@ -241,12 +239,28 @@
 
 	% XXX we don't handle `:- pragma foreign_import_module'.
 :- pred generate_foreign_header_code(foreign_language::in(managed_lang),
-		mlds_module_name::in, mlds__foreign_code::in,
+		module_name::in, mlds__foreign_code::in,
 		io__state::di, io__state::uo) is det.
 
-generate_foreign_header_code(Lang, _ModuleName, 
-		mlds__foreign_code(RevHeaderCode, _RevImports, _RevBodyCode,
+generate_foreign_header_code(Lang, ModuleName, 
+		mlds__foreign_code(RevHeaderCode, RevImports, _RevBodyCode,
 			_ExportDefns)) -->
+	{ Imports = list__reverse(RevImports) },
+	list__foldl(
+	    (pred(ForeignImport::in, di, uo) is det -->
+		(
+			{ Lang = managed_cplusplus }
+		->
+			module_name_to_search_file_name(
+					foreign__module_name(ForeignImport,
+							ModuleName),
+					".dll", FileName),
+			io__write_strings(["#using """, FileName, """\n"])
+	    	;
+			[]
+		)
+	    ), Imports),
+
 	{ HeaderCode = list__reverse(RevHeaderCode) },
 	io__write_list(HeaderCode, "\n", 
 		(pred(foreign_decl_code(CodeLang, Code, Context)::in,
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.254
diff -u -r1.254 modules.m
--- compiler/modules.m	29 Nov 2002 12:01:12 -0000	1.254
+++ compiler/modules.m	5 Dec 2002 15:45:49 -0000
@@ -2574,10 +2574,9 @@
 		    % of it sub-modules dlls, as they are referenced from
 		    % inside the top level dll.
 
+		module_name_to_file_name(ModuleName, ".dll", no, DllFileName),
 		{ SubModules = submodules(ModuleName, AllDeps) },
 		( { Target = il, SubModules \= [] } ->
-			module_name_to_file_name(ModuleName, ".dll", no,
-					DllFileName),
 			io__write_strings(DepStream, [DllFileName, " : "]),
 			write_dll_dependencies_list(SubModules, "", DepStream),
 			io__nl(DepStream)
@@ -2599,19 +2598,31 @@
 		% Handle dependencies introduced by
 		% `:- pragma foreign_import_module' declarations.
 		%
-		{ ForeignImportedModules =
-		    list__map(
-			(func(foreign_import_module(_, ForeignImportModule, _))
-				= ForeignImportModule),
-			ForeignImports) },
+		{ list__filter_map(
+			(pred(ForeignImportMod::in, Import::out) is semidet :-
+				Import = foreign__module_name(
+						ForeignImportMod,
+						SourceFileModuleName),
+
+				% We can't include mercury.dll as mmake
+				% can't find it, but we know that it exists.
+				Import \= unqualified("mercury")
+			), ForeignImports, ForeignImportedModules) },
 		( { ForeignImports = [] } ->
 			[]
 		;
+			{ Target = il ->
+				ForeignImportTarget = DllFileName,
+				ForeignImportExt = ".dll"
+			;
+				ForeignImportTarget = ObjFileName,
+				ForeignImportExt = ".mh"
+			},
 			io__write_string(DepStream, "\n\n"),
-			io__write_string(DepStream, ObjFileName),
+			io__write_string(DepStream, ForeignImportTarget),
 			io__write_string(DepStream, " : "),
-			write_dependencies_list(ForeignImportedModules, ".mh",
-				DepStream),
+			write_dependencies_list(ForeignImportedModules,
+					ForeignImportExt, DepStream),
 			io__write_string(DepStream, "\n\n")
 		),
 
@@ -2621,7 +2632,7 @@
 		->
 			{ Langs = set__to_sorted_list(LangSet) },
 			list__foldl(write_foreign_dependency_for_il(DepStream,
-				ModuleName, AllDeps), Langs)
+				ModuleName, AllDeps, ForeignImports), Langs)
 		;
 			[]
 		),
@@ -2835,10 +2844,10 @@
 	% scripts/Mmake.rules).
 	% 
 :- pred write_foreign_dependency_for_il(io__output_stream::in,sym_name::in,
-		list(module_name)::in, foreign_language::in,
-		io__state::di, io__state::uo) is det.
-write_foreign_dependency_for_il(DepStream, ModuleName, AllDeps, ForeignLang)
-		-->
+		list(module_name)::in, foreign_import_module_info::in,
+		foreign_language::in, io__state::di, io__state::uo) is det.
+write_foreign_dependency_for_il(DepStream, ModuleName, AllDeps,
+		ForeignImports, ForeignLang) -->
 	( 
 		{ ForeignModuleName = foreign_language_module_name(
 			ModuleName, ForeignLang) },
@@ -2871,6 +2880,8 @@
 			% CSHARP_ASSEMBLY_REFS-foreign_code_name
 			% the command line argument to reference all the
 			% dlls the foreign code module references.
+			%
+			% XXX Here we need to handle the foreign_import_modules
 			io__write_strings(DepStream, 
 				["CSHARP_ASSEMBLY_REFS-", 
 					ForeignModuleNameString, "="]),
@@ -2882,8 +2893,12 @@
 			;
 				Prefix = "/r:"
 			},
+			{ ForeignDeps = list__map((func(M) =
+						foreign__module_name(M, ModuleName)),
+					ForeignImports) },
+			{ Deps = AllDeps ++ ForeignDeps },
 			write_dll_dependencies_list(
-				referenced_dlls(ModuleName, AllDeps),
+				referenced_dlls(ModuleName, Deps),
 				Prefix, DepStream),
 			io__nl(DepStream)
 		;
@@ -4853,11 +4868,8 @@
 		Info = Info1 ^ module_contains_foreign_export :=
 				contains_foreign_export
 	;
-		% XXX handle lang \= c for
-		% `:- pragma foreign_import_module'.
 		Pragma = foreign_import_module(Lang, Import),
-		Lang = c,
-		list__member(c, BackendLangs)
+		list__member(Lang, BackendLangs)
 	->
 		Info = Info0 ^ all_foreign_import_module_info :=
 	    		[foreign_import_module(Lang, Import, Context) | 	
Index: compiler/prog_io_pragma.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_io_pragma.m,v
retrieving revision 1.52
diff -u -r1.52 prog_io_pragma.m
--- compiler/prog_io_pragma.m	26 Jul 2002 04:18:28 -0000	1.52
+++ compiler/prog_io_pragma.m	5 Dec 2002 15:45:56 -0000
@@ -179,12 +179,8 @@
 	    sym_name_and_args(ImportTerm, Import, [])
 	->
 	    ( parse_foreign_language(LangTerm, Language) ->
-		( Language = c ->
-		    Result = ok(pragma(
-		    	foreign_import_module(Language, Import)))
-		;
-		    Result = error("`:- pragma foreign_import_module' not yet supported for languages other than C", LangTerm)
-		)
+	    	Result = ok(pragma(
+			foreign_import_module(Language, Import)))
 	    ;
 		Result = error("invalid foreign language in `:- pragma foreign_import_module' declaration",
 			LangTerm)
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list