[m-dev.] for review: RTTI support for MLDS back-end
Fergus Henderson
fjh at cs.mu.OZ.AU
Tue Apr 18 07:57:16 AEST 2000
Estimated hours taken: 10
Implement RTTI support for the MLDS back-end using the rtti module.
compiler/ml_base_type_info.m:
Delete this file.
compiler/rtti_to_mlds.m:
New file, replaces ml_base_type_info.
This generates MLDS code from the RTTI data structures.
compiler/ml_code_gen.m:
Don't call ml_base_type_info.
compiler/mercury_compile.m:
Call rtti_to_mlds.
Also add a few more comments to the list of
imported modules.
compiler/mercury_compile.m:
compiler/type_ctor_info.m:
Delete the unnecessary second `module_info' parameter from
type_ctor_info_generate_rtti.
compiler/ml_code_util.m:
Add ml_gen_proc_params_from_rtti, for use by gen_init_proc_id
in rtti_to_mlds.
Fix a bug where it was using Arity for both the PredArity
and the TypeArity.
compiler/rtti.m:
compiler/rtti_out.m:
Change the documentation for rtti_out.m to say that it
_is_ intended to depend on LLDS.
Move rtti_data_to_name from rtti_out.m to rtti.m,
since that does not depend on the LLDS.
Add rtti__name_is_exported/1, and implement
rtti_name_linkage using that.
Add some new fields to rtti_proc_label, for use by
ml_gen_proc_params_from_rtti.
compiler/mlds.m:
Add a new alternative `rtti_type(rtti_name)' to mlds__type type,
and a new alternative `rtti_data(rtti_type_id, rtti_name)' to
the mlds__data_name type, so we can represent the names and
types of the RTTI data.
Change the mlds__initializer type to make it a bit more expressive,
so that it can represent e.g. initializers for arrays of structs,
since this is needed for some of the RTTI data.
compiler/ml_code_util.m:
compiler/ml_elim_nested.m:
compiler/mlds_to_c.m:
Handle the new definition of mlds__initializer,
and the new alternatives in the rtti_name and
mlds__data_name types.
Workspace: /home/pgrad/fjh/ws/hg
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.155
diff -u -d -r1.155 mercury_compile.m
--- compiler/mercury_compile.m 2000/04/02 08:09:20 1.155
+++ compiler/mercury_compile.m 2000/04/17 17:50:31
@@ -29,25 +29,42 @@
:- import_module library, getopt, set_bbbtree, term, varset.
:- import_module gc.
+ %
% the main compiler passes (mostly in order of execution)
+ %
+
+ % semantic analysis
:- import_module handle_options, prog_io, prog_out, modules, module_qual.
:- import_module equiv_type, make_hlds, typecheck, purity, polymorphism, modes.
:- import_module switch_detection, cse_detection, det_analysis, unique_modes.
-:- import_module stratify, check_typeclass, simplify, intermod, trans_opt.
-:- import_module table_gen.
-:- import_module bytecode_gen, bytecode.
-:- import_module (lambda), termination, higher_order, accumulator, inlining.
-:- import_module deforest, dnf, magic, dead_proc_elim.
-:- import_module unused_args, lco, saved_vars, liveness.
+:- import_module stratify, simplify.
+
+ % high-level HLDS transformations
+:- import_module check_typeclass, intermod, trans_opt, table_gen, (lambda).
+:- import_module type_ctor_info, termination, higher_order, accumulator.
+:- import_module inlining, deforest, dnf, magic, dead_proc_elim.
+:- import_module unused_args, lco.
+
+ % the LLDS back-end
+:- import_module saved_vars, liveness.
:- import_module follow_code, live_vars, arg_info, store_alloc, goal_path.
:- import_module code_gen, optimize, export.
-:- import_module type_ctor_info, base_typeclass_info.
-:- import_module rl_gen, rl_opt, rl_out.
+:- import_module base_typeclass_info.
:- import_module llds_common, transform_llds, llds_out.
:- import_module continuation_info, stack_layout.
-:- import_module mlds, ml_code_gen, ml_elim_nested, ml_tailcall, mlds_to_c.
+ % the Aditi-RL back-end
+:- import_module rl_gen, rl_opt, rl_out.
+ % the bytecode back-end
+:- import_module bytecode_gen, bytecode.
+
+ % the MLDS back-end
+:- import_module mlds.
+:- import_module ml_code_gen, ml_elim_nested, ml_tailcall.
+:- import_module rtti_to_mlds.
+:- import_module mlds_to_c.
+
% miscellaneous compiler modules
:- import_module prog_data, hlds_module, hlds_pred, hlds_out, llds, rl.
:- import_module mercury_to_mercury, mercury_to_goedel.
@@ -2027,11 +2044,23 @@
globals__io_lookup_bool_option(verbose, Verbose),
globals__io_lookup_bool_option(statistics, Stats),
globals__io_lookup_bool_option(common_data, CommonData),
- { type_ctor_info__generate_rtti(HLDS0, HLDS1, TypeCtorRttiData) },
+ %
+ % Here we generate the LLDS representations for
+ % various data structures used for RTTI, type classes,
+ % and stack layouts.
+ % XXX this should perhaps be part of backend_pass
+ % rather than output_pass.
+ %
+ { type_ctor_info__generate_rtti(HLDS0, TypeCtorRttiData) },
{ list__map(llds__wrap_rtti_data, TypeCtorRttiData, TypeCtorTables) },
- { base_typeclass_info__generate_llds(HLDS1, TypeClassInfos) },
- { stack_layout__generate_llds(HLDS1, HLDS, GlobalData,
+ { base_typeclass_info__generate_llds(HLDS0, TypeClassInfos) },
+ { stack_layout__generate_llds(HLDS0, HLDS, GlobalData,
PossiblyDynamicLayouts, StaticLayouts, LayoutLabels) },
+ %
+ % Here we perform some optimizations on the LLDS data.
+ % XXX this should perhaps be part of backend_pass
+ % rather than output_pass.
+ %
{ get_c_interface_info(HLDS, C_InterfaceInfo) },
{ global_data_get_all_proc_vars(GlobalData, GlobalVars) },
{ global_data_get_all_non_common_static_data(GlobalData,
@@ -2044,6 +2073,10 @@
{ CommonableData = CommonableData0 },
{ Procs1 = Procs0 }
),
+
+ %
+ % Next we put it all together and output it to one or more C files.
+ %
{ list__condense([CommonableData, NonCommonStaticData,
TypeCtorTables, TypeClassInfos, PossiblyDynamicLayouts],
AllData) },
@@ -2055,6 +2088,9 @@
{ C_InterfaceInfo = c_interface_info(_, _, _, C_ExportDecls, _) },
export__produce_header_file(C_ExportDecls, ModuleName),
+ %
+ % Finally we invoke the C compiler to compile it.
+ %
globals__io_lookup_bool_option(compile_to_c, CompileToC),
( { CompileToC = no } ->
mercury_compile__c_to_obj(ModuleName, NumChunks, CompileOK),
@@ -2209,15 +2245,34 @@
maybe_write_string(Verbose, "% Detecting tail calls...\n"),
ml_mark_tailcalls(MLDS0, MLDS1),
+ maybe_write_string(Verbose, "% done.\n"),
+ maybe_report_stats(Stats),
globals__io_lookup_bool_option(gcc_nested_functions, NestedFuncs),
( { NestedFuncs = no } ->
maybe_write_string(Verbose,
"% Flattening nested functions...\n"),
- ml_elim_nested(MLDS1, MLDS)
+ ml_elim_nested(MLDS1, MLDS2)
;
- { MLDS = MLDS1 }
- ).
+ { MLDS2 = MLDS1 }
+ ),
+ maybe_write_string(Verbose, "% done.\n"),
+ maybe_report_stats(Stats),
+
+ maybe_write_string(Verbose, "% Generating RTTI data...\n"),
+ { mercury_compile__mlds_gen_rtti_data(HLDS, MLDS2, MLDS) },
+ maybe_write_string(Verbose, "% done.\n"),
+ maybe_report_stats(Stats).
+
+:- pred mercury_compile__mlds_gen_rtti_data(module_info, mlds, mlds).
+:- mode mercury_compile__mlds_gen_rtti_data(in, in, out) is det.
+
+mercury_compile__mlds_gen_rtti_data(HLDS, MLDS0, MLDS) :-
+ type_ctor_info__generate_rtti(HLDS, TypeCtorRtti),
+ TypeCtorDefns = rtti_data_list_to_mlds(TypeCtorRtti),
+ MLDS0 = mlds(ModuleName, ForeignCode, Imports, Defns0),
+ list__append(TypeCtorDefns, Defns0, Defns),
+ MLDS = mlds(ModuleName, ForeignCode, Imports, Defns).
% The `--high-level-C' MLDS output pass
cvs diff: cannot find compiler/ml_base_type_info.m
Index: compiler/ml_code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_gen.m,v
retrieving revision 1.32
diff -u -d -r1.32 ml_code_gen.m
--- compiler/ml_code_gen.m 2000/03/30 05:41:47 1.32
+++ compiler/ml_code_gen.m 2000/04/17 16:56:57
@@ -599,7 +599,7 @@
:- implementation.
-:- import_module ml_base_type_info, ml_call_gen, ml_unify_gen, ml_code_util.
+:- import_module ml_call_gen, ml_unify_gen, ml_code_util.
:- import_module llds. % XXX needed for `code_model'.
:- import_module export, llds_out. % XXX needed for pragma C code
:- import_module hlds_pred, hlds_goal, hlds_data, prog_data.
@@ -660,8 +660,10 @@
:- pred ml_gen_types(module_info, mlds__defns, io__state, io__state).
:- mode ml_gen_types(in, out, di, uo) is det.
-ml_gen_types(ModuleInfo, MLDS_BaseTypeInfoDefns) -->
- { ml_base_type_info__generate_mlds(ModuleInfo, MLDS_BaseTypeInfoDefns) }.
+ml_gen_types(_ModuleInfo, MLDS_TypeDefns) -->
+ % XXX currently we use a low-level data representation,
+ % so we don't map Mercury types to MLDS types.
+ { MLDS_TypeDefns = [] }.
%-----------------------------------------------------------------------------%
%
@@ -1813,7 +1815,10 @@
string__append_list(["*", MangledModuleName, "__",
MangledVarName], Var_ArgName)
;
- sorry("complicated pragma c_code")
+ % XXX don't complain until run-time
+ % sorry("complicated pragma c_code")
+ Var_ArgName =
+ "*(fatal_error(""complicated pragma c_code""),(Word *)0)"
).
%-----------------------------------------------------------------------------%
Index: compiler/ml_code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_util.m,v
retrieving revision 1.5
diff -u -d -r1.5 ml_code_util.m
--- compiler/ml_code_util.m 2000/04/17 10:32:08 1.5
+++ compiler/ml_code_util.m 2000/04/17 21:35:49
@@ -101,6 +101,8 @@
%
:- func ml_gen_proc_params(module_info, pred_id, proc_id) = mlds__func_params.
+:- func ml_gen_proc_params_from_rtti(rtti_proc_label) = mlds__func_params.
+
% Generate the function prototype for a procedure with the
% given argument types, modes, and code model.
%
@@ -616,17 +618,52 @@
FuncParams = ml_gen_params(ModuleInfo, HeadVarNames, HeadTypes,
HeadModes, CodeModel).
+ % As above, but from the rtti_proc_id rather than
+ % from the module_info, pred_id, and proc_id.
+ %
+ml_gen_proc_params_from_rtti(RttiProcId) = FuncParams :-
+ VarSet = RttiProcId^proc_varset,
+ HeadVars = RttiProcId^proc_headvars,
+ ArgTypes = RttiProcId^arg_types,
+ ArgModes = RttiProcId^proc_arg_modes,
+ CodeModel = RttiProcId^proc_interface_code_model,
+
+ HeadVarNames = ml_gen_var_names(VarSet, HeadVars),
+
+ % XXX The setting of `UseNestedFunctions' to `no' is wrong!
+ % We ought to thread the globals through here.
+ % However, the UseNestedFunctions setting here
+ % is only used to compute the source type for a cast,
+ % and our current back-ends don't make use of that,
+ % so currently it's not a big deal.
+ UseNestedFunctions = no,
+
+ FuncParams = ml_gen_params_base(UseNestedFunctions, HeadVarNames,
+ ArgTypes, ArgModes, CodeModel).
+
% Generate the function prototype for a procedure with the
% given argument types, modes, and code model.
%
ml_gen_params(ModuleInfo, HeadVarNames, HeadTypes, HeadModes, CodeModel) =
FuncParams :-
+ modes_to_arg_modes(ModuleInfo, HeadModes, HeadTypes, ArgModes),
+ module_info_globals(ModuleInfo, Globals),
+ globals__lookup_bool_option(Globals, gcc_nested_functions,
+ NestedFunctions),
+ FuncParams = ml_gen_params_base(NestedFunctions, HeadVarNames,
+ HeadTypes, ArgModes, CodeModel).
+
+:- func ml_gen_params_base(bool, list(string), list(prog_type),
+ list(arg_mode), code_model) = mlds__func_params.
+
+ml_gen_params_base(NestedFunctions, HeadVarNames, HeadTypes, HeadModes,
+ CodeModel) = FuncParams :-
( CodeModel = model_semi ->
RetTypes = [mlds__native_bool_type]
;
RetTypes = []
),
- ml_gen_arg_decls(ModuleInfo, HeadVarNames, HeadTypes, HeadModes,
+ ml_gen_arg_decls(HeadVarNames, HeadTypes, HeadModes,
FuncArgs0),
( CodeModel = model_non ->
ContType = mlds__cont_type,
@@ -636,9 +673,7 @@
ContEnvName = data(var("cont_env_ptr")),
ContEnvArg = ContEnvName - ContEnvType,
(
- module_info_globals(ModuleInfo, Globals),
- globals__lookup_bool_option(Globals,
- gcc_nested_functions, yes)
+ NestedFunctions = yes
->
FuncArgs = list__append(FuncArgs0, [ContArg])
;
@@ -653,11 +688,11 @@
% Given the argument variable names, and corresponding lists of their
% types and modes, generate the MLDS argument list declaration.
%
-:- pred ml_gen_arg_decls(module_info, list(mlds__var_name), list(prog_type),
- list(mode), mlds__arguments).
-:- mode ml_gen_arg_decls(in, in, in, in, out) is det.
+:- pred ml_gen_arg_decls(list(mlds__var_name), list(prog_type), list(arg_mode),
+ mlds__arguments).
+:- mode ml_gen_arg_decls(in, in, in, out) is det.
-ml_gen_arg_decls(ModuleInfo, HeadVars, HeadTypes, HeadModes, FuncArgs) :-
+ml_gen_arg_decls(HeadVars, HeadTypes, HeadModes, FuncArgs) :-
(
HeadVars = [], HeadTypes = [], HeadModes = []
->
@@ -667,12 +702,12 @@
HeadTypes = [Type | Types],
HeadModes = [Mode | Modes]
->
- ml_gen_arg_decls(ModuleInfo, Vars, Types, Modes, FuncArgs0),
+ ml_gen_arg_decls(Vars, Types, Modes, FuncArgs0),
% exclude types such as io__state, etc.
( type_util__is_dummy_argument_type(Type) ->
FuncArgs = FuncArgs0
;
- ml_gen_arg_decl(ModuleInfo, Var, Type, Mode, FuncArg),
+ ml_gen_arg_decl(Var, Type, Mode, FuncArg),
FuncArgs = [FuncArg | FuncArgs0]
)
;
@@ -682,13 +717,13 @@
% Given an argument variable, and its type and mode,
% generate an MLDS argument declaration for it.
%
-:- pred ml_gen_arg_decl(module_info, var_name, prog_type, mode,
+:- pred ml_gen_arg_decl(var_name, prog_type, arg_mode,
pair(mlds__entity_name, mlds__type)).
-:- mode ml_gen_arg_decl(in, in, in, in, out) is det.
+:- mode ml_gen_arg_decl(in, in, in, out) is det.
-ml_gen_arg_decl(ModuleInfo, Var, Type, Mode, FuncArg) :-
+ml_gen_arg_decl(Var, Type, ArgMode, FuncArg) :-
MLDS_Type = mercury_type_to_mlds_type(Type),
- ( \+ mode_to_arg_mode(ModuleInfo, Mode, Type, top_in) ->
+ ( ArgMode \= top_in ->
MLDS_ArgType = mlds__ptr_type(MLDS_Type)
;
MLDS_ArgType = MLDS_Type
@@ -754,8 +789,10 @@
ml_gen_pred_label_from_rtti(RttiProcLabel, MLDS_PredLabel, MLDS_Module) :-
RttiProcLabel = rtti_proc_label(PredOrFunc, ThisModule, PredModule,
- PredName, Arity, ArgTypes, _PredId, ProcId, IsImported,
- _IsPseudoImported, _IsExported, IsSpecialPredInstance),
+ PredName, PredArity, ArgTypes, _PredId, ProcId,
+ _VarSet, _HeadVars, _ArgModes, _CodeModel,
+ IsImported, _IsPseudoImported, _IsExported,
+ IsSpecialPredInstance),
(
IsSpecialPredInstance = yes
->
@@ -765,7 +802,7 @@
% All type_ids here should be module qualified,
% since builtin types are handled separately in
% polymorphism.m.
- TypeId = qualified(TypeModule, TypeName) - Arity
+ TypeId = qualified(TypeModule, TypeName) - TypeArity
->
(
ThisModule \= TypeModule,
@@ -779,7 +816,7 @@
DeclaringModule = no
),
MLDS_PredLabel = special_pred(PredName,
- DeclaringModule, TypeName, Arity),
+ DeclaringModule, TypeName, TypeArity),
MLDS_Module = mercury_module_name_to_mlds(TypeModule)
;
string__append_list(["ml_gen_pred_label:\n",
@@ -803,7 +840,7 @@
MaybeDeclaringModule = no
),
MLDS_PredLabel = pred(PredOrFunc, MaybeDeclaringModule,
- PredName, Arity),
+ PredName, PredArity),
MLDS_Module = mercury_module_name_to_mlds(PredModule)
).
@@ -890,8 +927,7 @@
%
ml_gen_mlds_var_decl(DataName, MLDS_Type, Context) = MLDS_Defn :-
Name = data(DataName),
- MaybeInitializer = no,
- Defn = data(MLDS_Type, MaybeInitializer),
+ Defn = data(MLDS_Type, no_initializer),
DeclFlags = ml_gen_var_decl_flags,
MLDS_Defn = mlds__defn(Name, Context, DeclFlags, Defn).
Index: compiler/mlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds.m,v
retrieving revision 1.18
diff -u -d -r1.18 mlds.m
--- compiler/mlds.m 2000/03/30 05:41:51 1.18
+++ compiler/mlds.m 2000/04/17 16:59:17
@@ -261,7 +261,7 @@
:- interface.
-:- import_module hlds_pred, hlds_data, prog_data, builtin_ops.
+:- import_module hlds_pred, hlds_data, prog_data, builtin_ops, rtti.
% To avoid duplication, we use a few things from the LLDS.
% It would be nice to avoid this dependency...
@@ -380,7 +380,7 @@
% constants or variables
---> mlds__data(
mlds__type,
- maybe(mlds__initializer)
+ mlds__initializer
)
% functions
; mlds__function(
@@ -395,7 +395,12 @@
mlds__class_defn
).
-:- type mlds__initializer == list(mlds__rval).
+:- type mlds__initializer
+ ---> init_obj(mlds__rval)
+ ; init_struct(list(mlds__initializer))
+ ; init_array(list(mlds__initializer))
+ ; no_initializer
+ .
:- type mlds__func_params
---> mlds__func_params(
@@ -497,7 +502,9 @@
% closures for higher-order code.
; mlds__generic_env_ptr_type
- ; mlds__base_type_info_type.
+ ; mlds__base_type_info_type
+
+ ; mlds__rtti_type(rtti_name).
:- type mercury_type == prog_data__type.
@@ -1005,8 +1012,10 @@
% global constants. These are called "common"
% because they may be common sub-expressions.
%
- % Stuff for handling polymorphism and type classes
+ % Stuff for handling polymorphism and type classes,
+ % and RTTI.
%
+ ; rtti(rtti_type_id, rtti_name)
; type_ctor(mlds__base_data, string, arity)
% base_data, type name, type arity
; base_typeclass_info(hlds_data__class_id, string)
Index: compiler/mlds_to_c.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_c.m,v
retrieving revision 1.23
diff -u -d -r1.23 mlds_to_c.m
--- compiler/mlds_to_c.m 2000/03/30 05:41:52 1.23
+++ compiler/mlds_to_c.m 2000/04/17 17:27:32
@@ -32,11 +32,13 @@
:- implementation.
-:- import_module llds. % XXX needed for C interface types
-:- import_module llds_out. % XXX needed for llds_out__name_mangle.
+:- import_module llds. % XXX needed for C interface types
+:- import_module llds_out. % XXX needed for llds_out__name_mangle.
+:- import_module rtti. % for rtti__addr_to_string.
+:- import_module rtti_to_mlds. % for mlds_rtti_type_name.
+:- import_module hlds_pred. % for `pred_proc_id'.
:- import_module globals, options, passes_aux.
:- import_module builtin_ops, c_util, modules.
-:- import_module hlds_pred. % for `pred_proc_id'.
:- import_module prog_data, prog_out.
:- import_module bool, int, string, list, term, std_util, require.
@@ -356,7 +358,7 @@
mlds_output_decl_body(Indent, Name, DefnBody) -->
(
- { DefnBody = mlds__data(Type, _MaybeInitializer) },
+ { DefnBody = mlds__data(Type, _Initializer) },
mlds_output_data_decl(Name, Type)
;
{ DefnBody = mlds__function(MaybePredProcId, Signature,
@@ -375,8 +377,8 @@
mlds_output_defn_body(Indent, Name, Context, DefnBody) -->
(
- { DefnBody = mlds__data(Type, MaybeInitializer) },
- mlds_output_data_defn(Name, Type, MaybeInitializer)
+ { DefnBody = mlds__data(Type, Initializer) },
+ mlds_output_data_defn(Name, Type, Initializer)
;
{ DefnBody = mlds__function(MaybePredProcId, Signature,
MaybeBody) },
@@ -431,13 +433,12 @@
mlds_output_fully_qualified_name(Name).
:- pred mlds_output_data_defn(mlds__qualified_entity_name, mlds__type,
- maybe(mlds__initializer), io__state, io__state).
+ mlds__initializer, io__state, io__state).
:- mode mlds_output_data_defn(in, in, in, di, uo) is det.
-mlds_output_data_defn(Name, Type, MaybeInitializer) -->
+mlds_output_data_defn(Name, Type, Initializer) -->
mlds_output_data_decl(Name, Type),
- mlds_output_maybe(MaybeInitializer,
- mlds_output_initializer(Type)),
+ mlds_output_initializer(Type, Initializer),
io__write_string(";\n").
:- pred mlds_output_maybe(maybe(T), pred(T, io__state, io__state),
@@ -456,15 +457,28 @@
:- mode mlds_output_initializer(in, in, di, uo) is det.
mlds_output_initializer(_Type, Initializer) -->
- ( { Initializer = [SingleValue] } ->
- io__write_string(" = "),
- mlds_output_rval(SingleValue)
+ ( { Initializer = no_initializer } ->
+ []
;
- io__write_string(" = {\n\t\t"),
- io__write_list(Initializer, ",\n\t\t", mlds_output_rval),
- io__write_string("}")
+ io__write_string(" = "),
+ mlds_output_initializer_body(Initializer)
).
+:- pred mlds_output_initializer_body(mlds__initializer, io__state, io__state).
+:- mode mlds_output_initializer_body(in, di, uo) is det.
+
+mlds_output_initializer_body(no_initializer) --> [].
+mlds_output_initializer_body(init_obj(Rval)) -->
+ mlds_output_rval(Rval).
+mlds_output_initializer_body(init_struct(FieldInits)) -->
+ io__write_string("{\n\t\t"),
+ io__write_list(FieldInits, ",\n\t\t", mlds_output_initializer_body),
+ io__write_string("}").
+mlds_output_initializer_body(init_array(ElementInits)) -->
+ io__write_string("{\n\t\t"),
+ io__write_list(ElementInits, ",\n\t\t", mlds_output_initializer_body),
+ io__write_string("}").
+
%-----------------------------------------------------------------------------%
%
% Code to output function declarations/definitions
@@ -739,6 +753,9 @@
mlds_output_data_name(common(Num)) -->
io__write_string("common_"),
io__write_int(Num).
+mlds_output_data_name(rtti(RttiTypeId, RttiName)) -->
+ { rtti__addr_to_string(RttiTypeId, RttiName, RttiAddrName) },
+ io__write_string(RttiAddrName).
mlds_output_data_name(type_ctor(BaseData, Name, Arity)) -->
{ llds_out__name_mangle(Name, MangledName) },
io__write_string("base_type_"),
@@ -820,6 +837,9 @@
;
io__write_string("jmp_buf")
).
+mlds_output_type(mlds__rtti_type(RttiName)) -->
+ io__write_string("MR_"),
+ io__write_string(mlds_rtti_type_name(RttiName)).
%-----------------------------------------------------------------------------%
%
Index: compiler/ml_elim_nested.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_elim_nested.m,v
retrieving revision 1.5
diff -u -d -r1.5 ml_elim_nested.m
--- compiler/ml_elim_nested.m 2000/03/30 05:41:50 1.5
+++ compiler/ml_elim_nested.m 2000/04/17 16:47:07
@@ -330,8 +330,7 @@
EnvVarName = data(var("env")),
EnvVarFlags = env_decl_flags,
EnvVarType = mlds__class_type(qual(ModuleName, EnvClassName), 0),
- EnvVarInitializer = no,
- EnvVarDefnBody = mlds__data(EnvVarType, EnvVarInitializer),
+ EnvVarDefnBody = mlds__data(EnvVarType, no_initializer),
EnvVarDecl = mlds__defn(EnvVarName, Context, EnvVarFlags, EnvVarDefnBody),
%
@@ -405,8 +404,7 @@
EnvPtrVarName = data(var("env_ptr")),
EnvPtrVarFlags = env_decl_flags,
EnvPtrVarType = mlds__ptr_type(EnvVarType),
- EnvPtrVarInitializer = no,
- EnvPtrVarDefnBody = mlds__data(EnvPtrVarType, EnvPtrVarInitializer),
+ EnvPtrVarDefnBody = mlds__data(EnvPtrVarType, no_initializer),
EnvPtrVarDecl = mlds__defn(EnvPtrVarName, Context, EnvPtrVarFlags,
EnvPtrVarDefnBody),
@@ -431,8 +429,7 @@
ml_conv_arg_to_var(Context, Name - Type, LocalVar) :-
Flags = env_decl_flags,
- Initializer = no,
- DefnBody = mlds__data(Type, Initializer),
+ DefnBody = mlds__data(Type, no_initializer),
LocalVar = mlds__defn(Name, Context, Flags, DefnBody).
% Return the declaration flags appropriate for a local variable.
@@ -1079,8 +1076,8 @@
:- pred defn_body_contains_var(mlds__entity_defn, mlds__var).
:- mode defn_body_contains_var(in, in) is semidet.
-defn_body_contains_var(mlds__data(_Type, yes(Initializer)), Name) :-
- rvals_contains_var(Initializer, Name).
+defn_body_contains_var(mlds__data(_Type, Initializer), Name) :-
+ initializer_contains_var(Initializer, Name).
defn_body_contains_var(mlds__function(_PredProcId, _Params, MaybeBody),
Name) :-
maybe_statement_contains_var(MaybeBody, Name).
@@ -1088,6 +1085,19 @@
ClassDefn = mlds__class_defn(_Kind, _Imports, _Inherits, _Implements,
FieldDefns),
defns_contains_var(FieldDefns, Name).
+
+:- pred initializer_contains_var(mlds__initializer, mlds__var).
+:- mode initializer_contains_var(in, in) is semidet.
+
+initializer_contains_var(no_initializer, _) :- fail.
+initializer_contains_var(init_obj(Rval), Name) :-
+ rval_contains_var(Rval, Name).
+initializer_contains_var(init_struct(Inits), Name) :-
+ list__member(Init, Inits),
+ initializer_contains_var(Init, Name).
+initializer_contains_var(init_array(Inits), Name) :-
+ list__member(Init, Inits),
+ initializer_contains_var(Init, Name).
:- pred maybe_statement_contains_var(maybe(mlds__statement), mlds__var).
:- mode maybe_statement_contains_var(in, in) is semidet.
Index: compiler/rtti.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rtti.m,v
retrieving revision 1.4
diff -u -d -r1.4 rtti.m
--- compiler/rtti.m 2000/04/17 10:32:09 1.4
+++ compiler/rtti.m 2000/04/17 20:39:32
@@ -24,6 +24,7 @@
:- interface.
+:- import_module llds. % XXX for code_model
:- import_module hlds_module, hlds_pred.
:- import_module prog_data, pseudo_type_info.
@@ -317,6 +318,16 @@
; pseudo_type_info(pseudo_type_info)
; type_hashcons_pointer.
+ % convert a rtti_data to an rtti_type_id and an rtti_name.
+ % This calls error/1 if the argument is a type_var/1 rtti_data,
+ % since there is no rtti_type_id to return in that case.
+:- pred rtti_data_to_name(rtti_data::in, rtti_type_id::out, rtti_name::out)
+ is det.
+
+ % return yes iff the specified rtti_name should be exported
+ % for use by other modules.
+:- func rtti_name_is_exported(rtti_name) = bool.
+
% The rtti_proc_label type holds all the information about a procedure
% that we need to compute the entry label for that procedure
% in the target language (the llds__code_addr or mlds__code_addr).
@@ -330,6 +341,10 @@
arg_types :: list(type),
pred_id :: pred_id,
proc_id :: proc_id,
+ proc_varset :: prog_varset,
+ proc_headvars :: list(prog_var),
+ proc_arg_modes :: list(arg_mode),
+ proc_interface_code_model :: code_model,
%
% The following booleans hold values computed from the
% pred_info, using procedures
@@ -354,49 +369,112 @@
).
% Construct an rtti_proc_label for a given procedure.
-
:- func rtti__make_proc_label(module_info, pred_id, proc_id) = rtti_proc_label.
% Return the C variable name of the RTTI data structure identified
% by the input arguments.
% XXX this should be in rtti_out.m
-
:- pred rtti__addr_to_string(rtti_type_id::in, rtti_name::in, string::out)
is det.
% Return the C representation of a secondary tag location.
% XXX this should be in rtti_out.m
-
:- pred rtti__sectag_locn_to_string(sectag_locn::in, string::out) is det.
% Return the C representation of a type_ctor_rep value.
% XXX this should be in rtti_out.m
-
:- pred rtti__type_ctor_rep_to_string(type_ctor_rep::in, string::out) is det.
:- implementation.
-:- import_module code_util. % for code_util__compiler_defined
+:- import_module code_util. % for code_util__compiler_generated
:- import_module llds_out. % for name_mangle and sym_name_mangle
-:- import_module hlds_data, type_util.
+:- import_module hlds_data, type_util, mode_util.
:- import_module string, require.
+rtti_data_to_name(exist_locns(RttiTypeId, Ordinal, _),
+ RttiTypeId, exist_locns(Ordinal)).
+rtti_data_to_name(exist_info(RttiTypeId, Ordinal, _, _, _, _),
+ RttiTypeId, exist_info(Ordinal)).
+rtti_data_to_name(field_names(RttiTypeId, Ordinal, _),
+ RttiTypeId, field_names(Ordinal)).
+rtti_data_to_name(field_types(RttiTypeId, Ordinal, _),
+ RttiTypeId, field_types(Ordinal)).
+rtti_data_to_name(enum_functor_desc(RttiTypeId, _, Ordinal),
+ RttiTypeId, enum_functor_desc(Ordinal)).
+rtti_data_to_name(notag_functor_desc(RttiTypeId, _, _),
+ RttiTypeId, notag_functor_desc).
+rtti_data_to_name(du_functor_desc(RttiTypeId, _,_,_,_, Ordinal, _,_,_,_,_),
+ RttiTypeId, du_functor_desc(Ordinal)).
+rtti_data_to_name(enum_name_ordered_table(RttiTypeId, _),
+ RttiTypeId, enum_name_ordered_table).
+rtti_data_to_name(enum_value_ordered_table(RttiTypeId, _),
+ RttiTypeId, enum_value_ordered_table).
+rtti_data_to_name(du_name_ordered_table(RttiTypeId, _),
+ RttiTypeId, du_name_ordered_table).
+rtti_data_to_name(du_stag_ordered_table(RttiTypeId, Ptag, _),
+ RttiTypeId, du_stag_ordered_table(Ptag)).
+rtti_data_to_name(du_ptag_ordered_table(RttiTypeId, _),
+ RttiTypeId, du_ptag_ordered_table).
+rtti_data_to_name(type_ctor_info(RttiTypeId, _,_,_,_,_,_,_,_,_,_,_,_),
+ RttiTypeId, type_ctor_info).
+rtti_data_to_name(pseudo_type_info(PseudoTypeInfo), RttiTypeId,
+ pseudo_type_info(PseudoTypeInfo)) :-
+ RttiTypeId = pti_get_rtti_type_id(PseudoTypeInfo).
+
+:- func pti_get_rtti_type_id(pseudo_type_info) = rtti_type_id.
+pti_get_rtti_type_id(type_ctor_info(RttiTypeId)) = RttiTypeId.
+pti_get_rtti_type_id(type_info(RttiTypeId, _)) = RttiTypeId.
+pti_get_rtti_type_id(higher_order_type_info(RttiTypeId, _, _)) = RttiTypeId.
+pti_get_rtti_type_id(type_var(_)) = _ :-
+ error("rtti_data_to_name: type_var").
+
+rtti_name_is_exported(exist_locns(_)) = no.
+rtti_name_is_exported(exist_info(_)) = no.
+rtti_name_is_exported(field_names(_)) = no.
+rtti_name_is_exported(field_types(_)) = no.
+rtti_name_is_exported(enum_functor_desc(_)) = no.
+rtti_name_is_exported(notag_functor_desc) = no.
+rtti_name_is_exported(du_functor_desc(_)) = no.
+rtti_name_is_exported(enum_name_ordered_table) = no.
+rtti_name_is_exported(enum_value_ordered_table) = no.
+rtti_name_is_exported(du_name_ordered_table) = no.
+rtti_name_is_exported(du_stag_ordered_table(_)) = no.
+rtti_name_is_exported(du_ptag_ordered_table) = no.
+rtti_name_is_exported(type_ctor_info) = yes.
+rtti_name_is_exported(pseudo_type_info(Pseudo)) =
+ pseudo_type_info_is_exported(Pseudo).
+rtti_name_is_exported(type_hashcons_pointer) = no.
+
+:- func pseudo_type_info_is_exported(pseudo_type_info) = bool.
+pseudo_type_info_is_exported(type_var(_)) = no.
+pseudo_type_info_is_exported(type_ctor_info(_)) = yes.
+pseudo_type_info_is_exported(type_info(_, _)) = no.
+pseudo_type_info_is_exported(higher_order_type_info(_, _, _)) = no.
+
rtti__make_proc_label(ModuleInfo, PredId, ProcId) = ProcLabel :-
module_info_name(ModuleInfo, ThisModule),
- module_info_pred_info(ModuleInfo, PredId, PredInfo),
+ module_info_pred_proc_info(ModuleInfo, PredId, ProcId,
+ PredInfo, ProcInfo),
pred_info_get_is_pred_or_func(PredInfo, PredOrFunc),
pred_info_module(PredInfo, PredModule),
pred_info_name(PredInfo, PredName),
pred_info_arity(PredInfo, Arity),
pred_info_arg_types(PredInfo, ArgTypes),
+ proc_info_varset(ProcInfo, ProcVarSet),
+ proc_info_headvars(ProcInfo, ProcHeadVars),
+ proc_info_argmodes(ProcInfo, ProcModes),
+ proc_info_interface_code_model(ProcInfo, ProcCodeModel),
+ modes_to_arg_modes(ModuleInfo, ProcModes, ArgTypes, ProcArgModes),
IsImported = (pred_info_is_imported(PredInfo) -> yes ; no),
IsPseudoImp = (pred_info_is_pseudo_imported(PredInfo) -> yes ; no),
- IsExported = (pred_info_is_exported(PredInfo) -> yes ; no),
+ IsExported = (procedure_is_exported(PredInfo, ProcId) -> yes ; no),
IsSpecialPredInstance =
(code_util__compiler_generated(PredInfo) -> yes ; no),
ProcLabel = rtti_proc_label(PredOrFunc, ThisModule, PredModule,
PredName, Arity, ArgTypes, PredId, ProcId,
+ ProcVarSet, ProcHeadVars, ProcArgModes, ProcCodeModel,
IsImported, IsPseudoImp, IsExported, IsSpecialPredInstance).
rtti__addr_to_string(RttiTypeId, RttiName, Str) :-
Index: compiler/rtti_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rtti_out.m,v
retrieving revision 1.8
diff -u -d -r1.8 rtti_out.m
--- compiler/rtti_out.m 2000/04/17 10:32:09 1.8
+++ compiler/rtti_out.m 2000/04/17 17:33:04
@@ -4,14 +4,19 @@
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
%
-% Definitions of data structures for representing run-time type information
-% within the compiler, and code to output them.
+% This module contains code to output the RTTI data structures
+% defined in rtti.m as C code.
%
-% Eventually, this module will be independent of whether we are compiling
-% to LLDS or MLDS. For the time being, it depends on LLDS.
+% This module is part of the LLDS back-end. The decl_set data type
+% that it uses, which is defined in llds_out.m, represents a set of LLDS
+% declarations, and thus depends on the LLDS. Also the code to output
+% code_addrs depends on the LLDS.
%
-% Author: zs.
-
+% The MLDS back-end does not use this module; instead it converts the RTTI
+% data structures to MLDS (and then to C or Java, etc.).
+%
+% Main author: zs.
+%
%-----------------------------------------------------------------------------%
:- module rtti_out.
@@ -51,12 +56,6 @@
:- pred output_rtti_addr_storage_type_name(rtti_type_id::in, rtti_name::in,
bool::in, io__state::di, io__state::uo) is det.
- % convert a rtti_data to an rtti_type_id and an rtti_name.
- % This calls error/1 if the argument is a type_var/1 rtti_data,
- % since there is no rtti_type_id to return in that case.
-:- pred rtti_data_to_name(rtti_data::in, rtti_type_id::out, rtti_name::out)
- is det.
-
% Return true iff the given type of RTTI data structure includes
% code addresses.
:- pred rtti_name_would_include_code_addr(rtti_name::in, bool::out) is det.
@@ -468,43 +467,6 @@
DeclSet0, DeclSet)
).
-rtti_data_to_name(exist_locns(RttiTypeId, Ordinal, _),
- RttiTypeId, exist_locns(Ordinal)).
-rtti_data_to_name(exist_info(RttiTypeId, Ordinal, _, _, _, _),
- RttiTypeId, exist_info(Ordinal)).
-rtti_data_to_name(field_names(RttiTypeId, Ordinal, _),
- RttiTypeId, field_names(Ordinal)).
-rtti_data_to_name(field_types(RttiTypeId, Ordinal, _),
- RttiTypeId, field_types(Ordinal)).
-rtti_data_to_name(enum_functor_desc(RttiTypeId, _, Ordinal),
- RttiTypeId, enum_functor_desc(Ordinal)).
-rtti_data_to_name(notag_functor_desc(RttiTypeId, _, _),
- RttiTypeId, notag_functor_desc).
-rtti_data_to_name(du_functor_desc(RttiTypeId, _,_,_,_, Ordinal, _,_,_,_,_),
- RttiTypeId, du_functor_desc(Ordinal)).
-rtti_data_to_name(enum_name_ordered_table(RttiTypeId, _),
- RttiTypeId, enum_name_ordered_table).
-rtti_data_to_name(enum_value_ordered_table(RttiTypeId, _),
- RttiTypeId, enum_value_ordered_table).
-rtti_data_to_name(du_name_ordered_table(RttiTypeId, _),
- RttiTypeId, du_name_ordered_table).
-rtti_data_to_name(du_stag_ordered_table(RttiTypeId, Ptag, _),
- RttiTypeId, du_stag_ordered_table(Ptag)).
-rtti_data_to_name(du_ptag_ordered_table(RttiTypeId, _),
- RttiTypeId, du_ptag_ordered_table).
-rtti_data_to_name(type_ctor_info(RttiTypeId, _,_,_,_,_,_,_,_,_,_,_,_),
- RttiTypeId, type_ctor_info).
-rtti_data_to_name(pseudo_type_info(PseudoTypeInfo), RttiTypeId,
- pseudo_type_info(PseudoTypeInfo)) :-
- RttiTypeId = pti_get_rtti_type_id(PseudoTypeInfo).
-
-:- func pti_get_rtti_type_id(pseudo_type_info) = rtti_type_id.
-pti_get_rtti_type_id(type_ctor_info(RttiTypeId)) = RttiTypeId.
-pti_get_rtti_type_id(type_info(RttiTypeId, _)) = RttiTypeId.
-pti_get_rtti_type_id(higher_order_type_info(RttiTypeId, _, _)) = RttiTypeId.
-pti_get_rtti_type_id(type_var(_)) = _ :-
- error("rtti_data_to_name: type_var").
-
%-----------------------------------------------------------------------------%
:- pred output_generic_rtti_data_decl(rtti_type_id::in, rtti_name::in,
@@ -857,27 +819,11 @@
pseudo_type_info_would_incl_code_addr(type_info(_, _)) = no.
pseudo_type_info_would_incl_code_addr(higher_order_type_info(_, _, _)) = no.
-rtti_name_linkage(exist_locns(_), static).
-rtti_name_linkage(exist_info(_), static).
-rtti_name_linkage(field_names(_), static).
-rtti_name_linkage(field_types(_), static).
-rtti_name_linkage(enum_functor_desc(_), static).
-rtti_name_linkage(notag_functor_desc, static).
-rtti_name_linkage(du_functor_desc(_), static).
-rtti_name_linkage(enum_name_ordered_table, static).
-rtti_name_linkage(enum_value_ordered_table, static).
-rtti_name_linkage(du_name_ordered_table, static).
-rtti_name_linkage(du_stag_ordered_table(_), static).
-rtti_name_linkage(du_ptag_ordered_table, static).
-rtti_name_linkage(type_ctor_info, extern).
-rtti_name_linkage(pseudo_type_info(Pseudo), pseudo_type_info_linkage(Pseudo)).
-rtti_name_linkage(type_hashcons_pointer, static).
-
-:- func pseudo_type_info_linkage(pseudo_type_info) = linkage.
-pseudo_type_info_linkage(type_var(_)) = static.
-pseudo_type_info_linkage(type_ctor_info(_)) = extern.
-pseudo_type_info_linkage(type_info(_, _)) = static.
-pseudo_type_info_linkage(higher_order_type_info(_, _, _)) = static.
+rtti_name_linkage(RttiName, Linkage) :-
+ Exported = rtti_name_is_exported(RttiName),
+ ( Exported = yes, Linkage = extern
+ ; Exported = no, Linkage = static
+ ).
rtti_name_c_type(exist_locns(_), "MR_DuExistLocn", "[]").
rtti_name_c_type(exist_info(_), "MR_DuExistInfo", "").
Index: compiler/rtti_to_mlds.m
===================================================================
RCS file: rtti_to_mlds.m
diff -N rtti_to_mlds.m
--- /dev/null Thu Mar 30 14:06:13 2000
+++ rtti_to_mlds.m Tue Apr 18 05:41:59 2000
@@ -0,0 +1,436 @@
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2000 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.
+%-----------------------------------------------------------------------------%
+%
+% rtti_to_mlds.m: convert RTTI data structures to MLDS.
+% Author: fjh
+%
+% This module defines routines to convert from the back-end-independent
+% RTTI data structures into MLDS definitions.
+% The RTTI data structures are used for static data that is used
+% for handling RTTI, polymorphism, and typeclasses.
+%
+%-----------------------------------------------------------------------------%
+
+:- module rtti_to_mlds.
+:- interface.
+:- import_module rtti, mlds.
+:- import_module list.
+
+ % return a list of MLDS definitions for the given rtti_data list.
+:- func rtti_data_list_to_mlds(list(rtti_data)) = mlds__defns.
+
+ % return a name, consisting only of alphabetic characters,
+ % that would be suitable for the type name for the type
+ % of the given rtti_name.
+:- func mlds_rtti_type_name(rtti_name) = string.
+
+:- implementation.
+:- import_module pseudo_type_info, ml_code_util, prog_util, prog_out.
+:- import_module bool, list, std_util, string, term, require.
+
+rtti_data_list_to_mlds(RttiDatas) =
+ list__condense(list__map(rtti_data_to_mlds, RttiDatas)).
+
+ % return a list of MLDS definitions for the given rtti_data.
+:- func rtti_data_to_mlds(rtti_data) = mlds__defns.
+rtti_data_to_mlds(RttiData) = MLDS_Defns :-
+ ( RttiData = pseudo_type_info(type_var(_)) ->
+ % These just get represented as integers,
+ % so we don't need to define them.
+ % Also rtti_data_to_name/3 does not handle this case.
+ MLDS_Defns = []
+ ;
+ %
+ % Generate the name
+ %
+ rtti_data_to_name(RttiData, RttiTypeId, RttiName),
+ Name = data(rtti(RttiTypeId, RttiName)),
+
+ %
+ % Generate the context
+ %
+ % XXX the rtti_data ought to include a prog_context
+ % (the context of the corresponding type definition).
+ term__context_init(Context),
+ MLDS_Context = mlds__make_context(Context),
+
+ %
+ % Generate the declaration flags
+ %
+ Exported = rtti_name_is_exported(RttiName),
+ Flags = rtti_data_decl_flags(Exported),
+
+ %
+ % Generate the declaration body,
+ % i.e. the type and the initializer
+ %
+ MLDS_Type = rtti_type(RttiName),
+ Initializer = gen_init_rtti_data_defn(RttiData),
+ DefnBody = mlds__data(MLDS_Type, Initializer),
+
+ %
+ % put it all together
+ %
+ MLDS_Defn = mlds__defn(Name, MLDS_Context, Flags, DefnBody),
+ MLDS_Defns = [MLDS_Defn]
+ ).
+
+
+ % Return the declaration flags appropriate for an rtti_data.
+ %
+:- func rtti_data_decl_flags(bool) = mlds__decl_flags.
+rtti_data_decl_flags(Exported) = MLDS_DeclFlags :-
+ ( Exported = yes ->
+ Access = public
+ ;
+ Access = private
+ ),
+ PerInstance = per_instance,
+ Virtuality = non_virtual,
+ Finality = overridable,
+ Constness = const,
+ Abstractness = concrete,
+ MLDS_DeclFlags = init_decl_flags(Access, PerInstance,
+ Virtuality, Finality, Constness, Abstractness).
+
+%-----------------------------------------------------------------------------%
+
+ % Return an MLDS initializer for the given RTTI definition.
+:- func gen_init_rtti_data_defn(rtti_data) = mlds__initializer.
+
+gen_init_rtti_data_defn(exist_locns(_RttiTypeId, _Ordinal, Locns)) =
+ gen_init_array(gen_init_exist_locn, Locns).
+gen_init_rtti_data_defn(exist_info(RttiTypeId, _Ordinal, Plain, InTci, Tci,
+ Locns)) =
+ init_struct([
+ gen_init_int(Plain),
+ gen_init_int(InTci),
+ gen_init_int(Tci),
+ gen_init_rtti_name(RttiTypeId, Locns)
+ ]).
+gen_init_rtti_data_defn(field_names(_RttiTypeId, _Ordinal, MaybeNames)) =
+ gen_init_array(gen_init_maybe(gen_init_string), MaybeNames).
+gen_init_rtti_data_defn(field_types(_RttiTypeId, _Ordinal, Types)) =
+ gen_init_array(gen_init_cast_rtti_data, Types).
+gen_init_rtti_data_defn(enum_functor_desc(_RttiTypeId, FunctorName, Ordinal)) =
+ init_struct([
+ gen_init_string(FunctorName),
+ gen_init_int(Ordinal)
+ ]).
+gen_init_rtti_data_defn(notag_functor_desc(_RttiTypeId, FunctorName, ArgType)) =
+ init_struct([
+ gen_init_string(FunctorName),
+ gen_init_cast_rtti_data(ArgType)
+ ]).
+gen_init_rtti_data_defn(du_functor_desc(RttiTypeId, FunctorName, Ptag, Stag,
+ Locn, Ordinal, Arity, ContainsVarBitVector, ArgTypes,
+ MaybeNames, MaybeExist)) =
+ init_struct([
+ gen_init_string(FunctorName),
+ gen_init_int(Arity),
+ gen_init_int(ContainsVarBitVector),
+ gen_init_sectag_locn(Locn),
+ gen_init_int(Ptag),
+ gen_init_int(Stag),
+ gen_init_int(Ordinal),
+ gen_init_rtti_name(RttiTypeId, ArgTypes),
+ gen_init_maybe(gen_init_rtti_name(RttiTypeId), MaybeNames),
+ gen_init_maybe(gen_init_rtti_name(RttiTypeId), MaybeExist)
+ ]).
+gen_init_rtti_data_defn(enum_name_ordered_table(RttiTypeId, Functors)) =
+ gen_init_rtti_names_array(RttiTypeId, Functors).
+gen_init_rtti_data_defn(enum_value_ordered_table(RttiTypeId, Functors)) =
+ gen_init_rtti_names_array(RttiTypeId, Functors).
+gen_init_rtti_data_defn(du_name_ordered_table(RttiTypeId, Functors)) =
+ gen_init_rtti_names_array(RttiTypeId, Functors).
+gen_init_rtti_data_defn(du_stag_ordered_table(RttiTypeId, _Ptag, Sharers)) =
+ gen_init_rtti_names_array(RttiTypeId, Sharers).
+gen_init_rtti_data_defn(du_ptag_ordered_table(RttiTypeId, PtagLayouts)) =
+ gen_init_array(gen_init_ptag_layout_defn(RttiTypeId), PtagLayouts).
+gen_init_rtti_data_defn(type_ctor_info(RttiTypeId, UnifyProc, CompareProc,
+ CtorRep, SolverProc, InitProc, Version, NumPtags, NumFunctors,
+ FunctorsInfo, LayoutInfo, _MaybeHashCons,
+ _PrettyprinterProc)) = Initializer :-
+ RttiTypeId = rtti_type_id(Module, Type, TypeArity),
+ prog_out__sym_name_to_string(Module, ModuleName),
+ Initializer = init_struct([
+ gen_init_int(TypeArity),
+ gen_init_maybe_proc_id(UnifyProc),
+ gen_init_maybe_proc_id(UnifyProc),
+ gen_init_maybe_proc_id(CompareProc),
+ gen_init_type_ctor_rep(CtorRep),
+ gen_init_maybe_proc_id(SolverProc),
+ gen_init_maybe_proc_id(InitProc),
+ gen_init_string(ModuleName),
+ gen_init_string(Type),
+ gen_init_int(Version),
+ gen_init_functors_info(FunctorsInfo, RttiTypeId),
+ gen_init_layout_info(LayoutInfo, RttiTypeId),
+ gen_init_int(NumFunctors),
+ gen_init_int(NumPtags)
+ % These two are commented out while the corresponding
+ % fields of the MR_TypeCtorInfo_Struct type are
+ % commented out.
+ % gen_init_maybe(gen_init_rtti_name(RttiTypeId),
+ % MaybeHashCons),
+ % gen_init_maybe_proc_id(PrettyprinterProc)
+ ]).
+gen_init_rtti_data_defn(pseudo_type_info(Pseudo)) =
+ gen_init_pseudo_type_info_defn(Pseudo).
+
+:- func gen_init_functors_info(type_ctor_functors_info, rtti_type_id) =
+ mlds__initializer.
+
+gen_init_functors_info(enum_functors(EnumFunctorsInfo), RttiTypeId) =
+ gen_init_cast_rtti_name(RttiTypeId, EnumFunctorsInfo).
+gen_init_functors_info(notag_functors(NotagFunctorsInfo), RttiTypeId) =
+ gen_init_cast_rtti_name(RttiTypeId, NotagFunctorsInfo).
+gen_init_functors_info(du_functors(DuFunctorsInfo), RttiTypeId) =
+ gen_init_cast_rtti_name(RttiTypeId, DuFunctorsInfo).
+gen_init_functors_info(no_functors, _) =
+ gen_init_null_pointer.
+
+:- func gen_init_layout_info(type_ctor_layout_info, rtti_type_id) =
+ mlds__initializer.
+
+gen_init_layout_info(enum_layout(EnumLayoutInfo), RttiTypeId) =
+ gen_init_cast_rtti_name(RttiTypeId, EnumLayoutInfo).
+gen_init_layout_info(notag_layout(NotagLayoutInfo), RttiTypeId) =
+ gen_init_cast_rtti_name(RttiTypeId, NotagLayoutInfo).
+gen_init_layout_info(du_layout(DuLayoutInfo), RttiTypeId) =
+ gen_init_cast_rtti_name(RttiTypeId, DuLayoutInfo).
+gen_init_layout_info(equiv_layout(EquivTypeInfo), _RttiTypeId) =
+ gen_init_cast_rtti_data(EquivTypeInfo).
+gen_init_layout_info(no_layout, _RttiTypeId) =
+ gen_init_null_pointer.
+
+:- func gen_init_maybe_proc_id(maybe(rtti_proc_label)) = mlds__initializer.
+
+gen_init_maybe_proc_id(MaybeProcLabel) =
+ gen_init_maybe(gen_init_proc_id, MaybeProcLabel).
+
+:- func gen_init_pseudo_type_info_defn(pseudo_type_info) = mlds__initializer.
+
+gen_init_pseudo_type_info_defn(type_var(_)) = _ :-
+ error("gen_init_pseudo_type_info_defn: type_var").
+gen_init_pseudo_type_info_defn(type_ctor_info(_)) = _ :-
+ error("gen_init_pseudo_type_info_defn: type_ctor_info").
+gen_init_pseudo_type_info_defn(type_info(RttiTypeId, ArgTypes)) = Init :-
+ ArgRttiDatas = list__map(func(P) = pseudo_type_info(P), ArgTypes),
+ Init = init_struct([
+ gen_init_rtti_name(RttiTypeId, type_ctor_info),
+ gen_init_cast_rtti_datas_array(ArgRttiDatas)
+ ]).
+gen_init_pseudo_type_info_defn(higher_order_type_info(RttiTypeId,
+ Arity, ArgTypes)) = Init :-
+ ArgRttiDatas = list__map(func(P) = pseudo_type_info(P), ArgTypes),
+ Init = init_struct([
+ gen_init_rtti_name(RttiTypeId, type_ctor_info),
+ gen_init_int(Arity),
+ gen_init_cast_rtti_datas_array(ArgRttiDatas)
+ ]).
+
+:- func gen_init_ptag_layout_defn(rtti_type_id, du_ptag_layout) =
+ mlds__initializer.
+
+gen_init_ptag_layout_defn(RttiTypeId, DuPtagLayout) = Init :-
+ DuPtagLayout = du_ptag_layout(NumSharers, Locn, Descriptors) ,
+ Init = init_struct([
+ gen_init_int(NumSharers),
+ gen_init_sectag_locn(Locn),
+ gen_init_rtti_name(RttiTypeId, Descriptors)
+ ]).
+
+%-----------------------------------------------------------------------------%
+
+:- func gen_init_rtti_names_array(rtti_type_id, list(rtti_name)) =
+ mlds__initializer.
+gen_init_rtti_names_array(RttiTypeId, RttiNames) =
+ gen_init_array(gen_init_rtti_name(RttiTypeId), RttiNames).
+
+:- func gen_init_rtti_datas_array(list(rtti_data)) = mlds__initializer.
+gen_init_rtti_datas_array(RttiDatas) =
+ gen_init_array(gen_init_rtti_data, RttiDatas).
+
+:- func gen_init_cast_rtti_datas_array(list(rtti_data)) = mlds__initializer.
+gen_init_cast_rtti_datas_array(RttiDatas) =
+ gen_init_array(gen_init_cast_rtti_data, RttiDatas).
+
+ % Generate the MLDS initializer comprising the rtti_name
+ % for a given rtti_data, converted to mlds__generic_type.
+:- func gen_init_cast_rtti_data(rtti_data) = mlds__initializer.
+
+gen_init_cast_rtti_data(RttiData) = Initializer :-
+ ( RttiData = pseudo_type_info(type_var(VarNum)) ->
+ % rtti_data_to_name/3 does not handle this case
+ Initializer = init_obj(unop(box(mlds__native_int_type),
+ const(int_const(VarNum))))
+ ;
+ rtti_data_to_name(RttiData, RttiTypeId, RttiName),
+ Initializer = gen_init_cast_rtti_name(RttiTypeId, RttiName)
+ ).
+
+ % Generate the MLDS initializer comprising the rtti_name
+ % for a given rtti_data.
+:- func gen_init_rtti_data(rtti_data) = mlds__initializer.
+
+gen_init_rtti_data(RttiData) = Initializer :-
+ rtti_data_to_name(RttiData, RttiTypeId, RttiName),
+ Initializer = gen_init_rtti_name(RttiTypeId, RttiName).
+
+ % Generate an MLDS initializer comprising just the
+ % the rval for a given rtti_name
+:- func gen_init_rtti_name(rtti_type_id, rtti_name) = mlds__initializer.
+
+gen_init_rtti_name(RttiTypeId, RttiName) =
+ init_obj(gen_rtti_name(RttiTypeId, RttiName)).
+
+ % Generate the MLDS initializer comprising the rtti_name
+ % for a given rtti_name, converted to mlds__generic_type.
+:- func gen_init_cast_rtti_name(rtti_type_id, rtti_name) = mlds__initializer.
+
+gen_init_cast_rtti_name(RttiTypeId, RttiName) =
+ init_obj(unop(box(rtti_type(RttiName)),
+ gen_rtti_name(RttiTypeId, RttiName))).
+
+ % Generate the MLDS rval for an rtti_name.
+:- func gen_rtti_name(rtti_type_id, rtti_name) = mlds__rval.
+
+gen_rtti_name(RttiTypeId, RttiName) = Rval :-
+ RttiTypeId = rtti_type_id(ModuleName, _Type, _TypeArity),
+ MLDS_ModuleName = mercury_module_name_to_mlds(ModuleName),
+ MLDS_DataName = rtti(RttiTypeId, RttiName),
+ DataAddr = data_addr(MLDS_ModuleName, MLDS_DataName),
+ Rval = const(data_addr_const(DataAddr)).
+
+:- func gen_init_exist_locn(exist_typeinfo_locn) = mlds__initializer.
+
+gen_init_exist_locn(plain_typeinfo(SlotInCell)) =
+ init_struct([
+ gen_init_int(SlotInCell),
+ gen_init_int(-1)
+ ]).
+gen_init_exist_locn(typeinfo_in_tci(SlotInCell, SlotInTci)) =
+ init_struct([
+ gen_init_int(SlotInCell),
+ gen_init_int(SlotInTci)
+ ]).
+
+%-----------------------------------------------------------------------------%
+
+:- func gen_init_proc_id(rtti_proc_label) = mlds__initializer.
+gen_init_proc_id(RttiProcId) = Init :-
+ %
+ % construct an rval for the address of this procedure
+ % (this is similar to ml_gen_proc_addr_rval)
+ %
+ ml_gen_pred_label_from_rtti(RttiProcId, PredLabel, PredModule),
+ ProcId = RttiProcId^proc_id,
+ QualifiedProcLabel = qual(PredModule, PredLabel - ProcId),
+ Params = ml_gen_proc_params_from_rtti(RttiProcId),
+ Signature = mlds__get_func_signature(Params),
+ ProcAddrRval = const(code_addr_const(proc(QualifiedProcLabel,
+ Signature))),
+ %
+ % Convert the procedure address to a generic type.
+ % We need to use a generic type because since the actual type
+ % for the procedure will depend on how many type_info parameters
+ % it takes, which will depend on the type's arity.
+ %
+ ProcAddrArg = unop(box(mlds__func_type(Params)), ProcAddrRval),
+ Init = init_obj(ProcAddrArg).
+
+%-----------------------------------------------------------------------------%
+%
+% Conversion functions for builtin enumeration types.
+%
+% This handles sectag_locn and type_ctor_rep.
+% The rvals generated are just named constants in
+% the private_builtin module, which the Mercury
+% runtime is expected to define.
+
+:- func gen_init_sectag_locn(sectag_locn) = mlds__initializer.
+gen_init_sectag_locn(Locn) = gen_init_builtin_const(Name) :-
+ rtti__sectag_locn_to_string(Locn, Name).
+
+:- func gen_init_type_ctor_rep(type_ctor_rep) = mlds__initializer.
+gen_init_type_ctor_rep(Rep) = gen_init_builtin_const(Name) :-
+ rtti__type_ctor_rep_to_string(Rep, Name).
+
+:- func gen_init_builtin_const(string) = mlds__initializer.
+gen_init_builtin_const(Name) = init_obj(Rval) :-
+ mercury_private_builtin_module(PrivateBuiltin),
+ MLDS_Module = mercury_module_name_to_mlds(PrivateBuiltin),
+ Rval = lval(var(qual(MLDS_Module, Name))).
+
+%-----------------------------------------------------------------------------%
+%
+% Conversion functions for the basic types.
+%
+% This handles arrays, maybe, null pointers, strings, and ints.
+%
+
+:- func gen_init_array(func(T) = mlds__initializer, list(T)) =
+ mlds__initializer.
+
+gen_init_array(Conv, List) = init_array(list__map(Conv, List)).
+
+:- func gen_init_maybe(func(T) = mlds__initializer, maybe(T)) =
+ mlds__initializer.
+
+gen_init_maybe(Conv, yes(X)) = Conv(X).
+gen_init_maybe(_, no) = gen_init_null_pointer.
+
+:- func gen_init_null_pointer = mlds__initializer.
+
+gen_init_null_pointer =
+ % XXX the MLDS ought to have a null pointer constant
+ init_obj(mlds__unop(cast(mlds__generic_type), const(int_const(0)))).
+
+:- func gen_init_string(string) = mlds__initializer.
+
+gen_init_string(String) = init_obj(const(string_const(String))).
+
+:- func gen_init_int(int) = mlds__initializer.
+
+gen_init_int(Int) = init_obj(const(int_const(Int))).
+
+%-----------------------------------------------------------------------------%
+
+mlds_rtti_type_name(exist_locns(_)) = "DuExistLocnArray".
+mlds_rtti_type_name(exist_info(_)) = "DuExistInfo".
+mlds_rtti_type_name(field_names(_)) = "ConstStringArray".
+mlds_rtti_type_name(field_types(_)) = "PseudoTypeInfoArray".
+mlds_rtti_type_name(enum_functor_desc(_)) = "EnumFunctorDesc".
+mlds_rtti_type_name(notag_functor_desc) = "NotagFunctorDesc".
+mlds_rtti_type_name(du_functor_desc(_)) = "DuFunctorDesc".
+mlds_rtti_type_name(enum_name_ordered_table) = "EnumFunctorDescPtrArray".
+mlds_rtti_type_name(enum_value_ordered_table) = "EnumFunctorDescPtrArray".
+mlds_rtti_type_name(du_name_ordered_table) = "DuFunctorDescPtrArray".
+mlds_rtti_type_name(du_stag_ordered_table(_)) = "DuFunctorDescPtrArray".
+mlds_rtti_type_name(du_ptag_ordered_table) = "DuPtagLayoutArray".
+mlds_rtti_type_name(type_ctor_info) = "TypeCtorInfo_Struct".
+mlds_rtti_type_name(pseudo_type_info(Pseudo)) =
+ mlds_pseudo_type_info_type_name(Pseudo).
+mlds_rtti_type_name(type_hashcons_pointer) = "TableNodePtrPtr".
+
+:- func mlds_pseudo_type_info_type_name(pseudo_type_info) = string.
+
+mlds_pseudo_type_info_type_name(type_var(_)) = _ :-
+ % we use small integers to represent type_vars,
+ % rather than pointers, so there is no pointed-to type
+ error("mlds_rtti_type_name: type_var").
+mlds_pseudo_type_info_type_name(type_ctor_info(_)) =
+ "TypeCtorInfo_Struct".
+mlds_pseudo_type_info_type_name(type_info(_TypeId, ArgTypes)) =
+ string__format("FO_PseudoTypeInfo_Struct%d",
+ [i(list__length(ArgTypes))]).
+mlds_pseudo_type_info_type_name(higher_order_type_info(_TypeId, _Arity,
+ ArgTypes)) =
+ string__format("HO_PseudoTypeInfo_Struct%d",
+ [i(list__length(ArgTypes))]).
+
+%-----------------------------------------------------------------------------%
Index: compiler/type_ctor_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/type_ctor_info.m,v
retrieving revision 1.6
diff -u -d -r1.6 type_ctor_info.m
--- compiler/type_ctor_info.m 2000/04/17 10:32:10 1.6
+++ compiler/type_ctor_info.m 2000/04/17 11:06:45
@@ -45,8 +45,8 @@
:- pred type_ctor_info__generate_hlds(module_info::in, module_info::out)
is det.
-:- pred type_ctor_info__generate_rtti(module_info::in, module_info::out,
- list(rtti_data)::out) is det.
+:- pred type_ctor_info__generate_rtti(module_info::in, list(rtti_data)::out)
+ is det.
:- implementation.
@@ -145,7 +145,7 @@
%---------------------------------------------------------------------------%
-type_ctor_info__generate_rtti(ModuleInfo, ModuleInfo, Tables) :-
+type_ctor_info__generate_rtti(ModuleInfo, Tables) :-
module_info_type_ctor_gen_infos(ModuleInfo, TypeCtorGenInfos),
type_ctor_info__construct_type_ctor_infos(TypeCtorGenInfos,
ModuleInfo, [], Dynamic, [], Static0),
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list