%-----------------------------------------------------------------------------% % vim: ft=mercury ts=4 sw=4 et %-----------------------------------------------------------------------------% % Copyright (C) 1996-2011 The University of Melbourne. % This file may only be copied under the terms of the GNU General % Public License - see the file COPYING in the Mercury distribution. %-----------------------------------------------------------------------------% % % File: export.m. % Main author: dgj, juliensf. % % This module defines predicates to produce the functions which are % exported to a foreign language via a `pragma foreign_export' declaration. % %-----------------------------------------------------------------------------% :- module backend_libs.export. :- interface. :- import_module hlds. :- import_module hlds.hlds_module. :- import_module mdbcomp. :- import_module mdbcomp.prim_data. :- import_module parse_tree. :- import_module parse_tree.prog_data. :- import_module parse_tree.prog_foreign. :- import_module io. %-----------------------------------------------------------------------------% % From the module_info, get a list of foreign_export_decls, each of which % holds information about the declaration of a foreign function named in a % `pragma foreign_export' declaration, which is used to allow a call to % be made to a Mercury procedure from the foreign language. % :- pred get_foreign_export_decls(module_info::in, foreign_export_decls::out) is det. % From the module_info, get a list of foreign_export_defns, each of which % is a string containing the foreign code for defining a foreign function % named in a `pragma foreign_export' decl. % :- pred get_foreign_export_defns(module_info::in, foreign_export_defns::out) is det. % Produce an interface file containing declarations for the exported % foreign functions (if required in this foreign language). % :- pred produce_header_file(module_info::in, foreign_export_decls::in, module_name::in, io::di, io::uo) is det. %-----------------------------------------------------------------------------% % Utilities for generating C code which interfaces with Mercury. % The {MLDS,LLDS}->C backends and fact tables use this code. % Generate C code to convert an rval (represented as a string), from % a C type to a mercury C type (ie. convert strings and floats to % words) and return the resulting C code as a string. % :- pred convert_type_to_mercury(string::in, mer_type::in, string::out) is det. % Generate C code to convert an rval (represented as a string), from % a mercury C type to a C type. (ie. convert words to strings and % floats if required) and return the resulting C code as a string. % :- pred convert_type_from_mercury(string::in, mer_type::in, string::out) is det. % Succeeds iff the given C type is known by the compiler to be an integer % or pointer type the same size as MR_Word. % :- pred c_type_is_word_sized_int_or_ptr(string::in) is semidet. %-----------------------------------------------------------------------------% %-----------------------------------------------------------------------------% :- implementation. :- import_module backend_libs.c_util. :- import_module backend_libs.foreign. :- import_module backend_libs.name_mangle. :- import_module backend_libs.proc_label. :- import_module check_hlds. :- import_module check_hlds.type_util. :- import_module hlds.arg_info. :- import_module hlds.code_model. :- import_module hlds.hlds_data. :- import_module hlds.hlds_pred. :- import_module hlds.pred_table. :- import_module libs. :- import_module libs.globals. :- import_module parse_tree.file_names. :- import_module parse_tree.module_cmds. :- import_module parse_tree.prog_foreign. :- import_module parse_tree.prog_util. :- import_module assoc_list. :- import_module bool. :- import_module int. :- import_module library. :- import_module list. :- import_module map. :- import_module maybe. :- import_module pair. :- import_module require. :- import_module string. :- import_module term. %-----------------------------------------------------------------------------% get_foreign_export_decls(HLDS, ForeignExportDecls) :- module_info_get_predicate_table(HLDS, PredicateTable), predicate_table_get_preds(PredicateTable, Preds), module_info_get_foreign_decl(HLDS, RevForeignDecls), ForeignDecls = list.reverse(RevForeignDecls), module_info_get_pragma_exported_procs(HLDS, ExportedProcs), module_info_get_globals(HLDS, Globals), get_foreign_export_decls_2(Preds, ExportedProcs, Globals, HLDS, ExportDecls), ForeignExportDecls = foreign_export_decls(ForeignDecls, ExportDecls). :- pred get_foreign_export_decls_2(pred_table::in, list(pragma_exported_proc)::in, globals::in, module_info::in, list(foreign_export_decl)::out) is det. get_foreign_export_decls_2(_Preds, [], _, _, []). get_foreign_export_decls_2(Preds, [E | ExportedProcs], Globals, ModuleInfo, ExportDecls) :- E = pragma_exported_proc(Lang, PredId, ProcId, ExportName, _Ctxt), ( Lang = lang_c, get_export_info_for_lang_c(Preds, PredId, ProcId, Globals, ModuleInfo, _HowToDeclare, RetType, _DeclareReturnVal, _FailureAction, _SuccessAction, HeadArgInfoTypes), get_argument_declarations_for_lang_c(HeadArgInfoTypes, no, ModuleInfo, ArgDecls) ; ( Lang = lang_csharp ; Lang = lang_java ; Lang = lang_il ; Lang = lang_erlang ), sorry($module, $pred, ":- pragma foreign_export for non-C backends.") ), ExportDecl = foreign_export_decl(Lang, RetType, ExportName, ArgDecls), get_foreign_export_decls_2(Preds, ExportedProcs, Globals, ModuleInfo, ExportDecls0), ExportDecls = [ExportDecl | ExportDecls0]. %-----------------------------------------------------------------------------% get_foreign_export_defns(ModuleInfo, ExportedProcsCode) :- module_info_get_pragma_exported_procs(ModuleInfo, ExportedProcs), module_info_get_predicate_table(ModuleInfo, PredicateTable), predicate_table_get_preds(PredicateTable, Preds), to_c(Preds, ExportedProcs, ModuleInfo, ExportedProcsCode). % For each exported procedure, produce a C function. % The code we generate is in the form % % MR_declare_entry(