%-----------------------------------------------------------------------------% % Copyright (C) 1996-1998 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. %-----------------------------------------------------------------------------% % This module defines predicates to produce the functions which are % exported to C via a `pragma export' declaration. % Note: any changes here might also require similar changes to the handling % of `pragma import' declarations, which are handled in make_hlds.m. % Main authors: dgj. %-----------------------------------------------------------------------------% :- module export. :- interface. :- import_module hlds_module, prog_data, llds. :- import_module io. % From the module_info, get a list of c_export_decls, % each of which holds information about the declaration % of a C function named in a `pragma export' declaration, % which is used to allow a call to be made to a Mercury % procedure from C. :- pred export__get_c_export_decls(module_info, c_export_decls). :- mode export__get_c_export_decls(in, out) is det. % From the module_info, get a list of c_export_defns, % each of which is a string containing the C code % for defining a C function named in a `pragma export' decl. :- pred export__get_c_export_defns(module_info, c_export_defns). :- mode export__get_c_export_defns(in, out) is det. % Produce a header file containing prototypes for the exported C % functions :- pred export__produce_header_file(c_export_decls, module_name, io__state, io__state). :- mode export__produce_header_file(in, in, di, uo) is det. % Convert the type, to a string corresponding to its C type. % (Defaults to Word). :- pred export__type_to_type_string(type, string). :- mode export__type_to_type_string(in, out) is det. % 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, type, string). :- mode convert_type_to_mercury(in, in, 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, type, string). :- mode convert_type_from_mercury(in, in, out) is det. % Certain types, namely io__state and store__store(S), % are just dummy types used to ensure logical semantics; % there is no need to actually pass them, and so when % importing or exporting procedures to/from C, we don't % include arguments with these types. :- pred export__exclude_argument_type(type). :- mode export__exclude_argument_type(in) is semidet. %-----------------------------------------------------------------------------% %-----------------------------------------------------------------------------% :- implementation. :- import_module code_gen, code_util, hlds_pred, llds_out, modules. :- import_module term, varset. :- import_module library, map, int, string, std_util, assoc_list, require. :- import_module list, bool. %-----------------------------------------------------------------------------% export__get_c_export_decls(HLDS, C_ExportDecls) :- module_info_get_predicate_table(HLDS, PredicateTable), predicate_table_get_preds(PredicateTable, Preds), module_info_get_pragma_exported_procs(HLDS, ExportedProcs), export__get_c_export_decls_2(Preds, ExportedProcs, C_ExportDecls). :- pred export__get_c_export_decls_2(pred_table, list(pragma_exported_proc), list(c_export_decl)). :- mode export__get_c_export_decls_2(in, in, out) is det. export__get_c_export_decls_2(_Preds, [], []). export__get_c_export_decls_2(Preds, [E|ExportedProcs], C_ExportDecls) :- E = pragma_exported_proc(PredId, ProcId, C_Function), get_export_info(Preds, PredId, ProcId, C_RetType, _DeclareReturnVal, _FailureAction, _SuccessAction, HeadArgInfoTypes), get_argument_declarations(HeadArgInfoTypes, no, ArgDecls), C_ExportDecl = c_export_decl(C_RetType, C_Function, ArgDecls), export__get_c_export_decls_2(Preds, ExportedProcs, C_ExportDecls0), C_ExportDecls = [C_ExportDecl | C_ExportDecls0]. %-----------------------------------------------------------------------------% export__get_c_export_defns(Module, ExportedProcsCode) :- module_info_get_pragma_exported_procs(Module, ExportedProcs), module_info_get_predicate_table(Module, PredicateTable), predicate_table_get_preds(PredicateTable, Preds), export__to_c(Preds, ExportedProcs, Module, ExportedProcsCode). % For each exported procedure, produce a C function. % The code we generate is in the form % % #if SEMIDET % bool % #elif FUNCTION % Word % #else % void % #endif % (Word Mercury__Argument1, Word *Mercury__Argument2...) % /* Word for input, Word* for output */ % { % #if NUM_REAL_REGS > 0 % Word c_regs[NUM_REAL_REGS]; % #endif % #if FUNCTION % Word retval; % #endif % % /* save the registers that our C caller may be using */ % save_regs_to_mem(c_regs); % % /* restore Mercury's registers that were saved as */ % /* we entered C from Mercury (the process must */ % /* always start in Mercury so that we can */ % /* init_engine() etc.) */ % restore_registers(); % % /* save the registers which may be clobbered */ % /* by the C function call call_engine(). */ % save_transient_registers(); % { % Declare_entry(