[m-dev.] for review: MLDS back-end: implement typeclasses
Fergus Henderson
fjh at cs.mu.OZ.AU
Thu May 11 03:09:36 AEST 2000
Sorry, I was a little bit premature in posting that diff.
Testing revealed that I had managed to break the LLDS back-end.
So I've made the following additional changes.
(I've enclosed first a relative diff, then a full diff
for the affected files.)
--- CHANGES16.old Thu May 11 02:53:58 2000
+++ CHANGES16 Thu May 11 03:02:53 2000
@@ -61,7 +61,14 @@
compiler/llds_out.m:
compiler/rtti_out.m:
- Move the code for handling dynamic initialization of
+ Change llds_out.m so that it calls a new predicate
+ output_base_typeclass_info_storage_type_name, defined in
+ rtti_out.m, when outputting base_typeclass_info declarations.
+ This is needed because base_typeclass_infos are now defined
+ as RTTI constants with type `Code * []', and so need to be
+ handled as such by rtti_out.m rather than being assumed to
+ be structs like the other LLDS data_names.
+ Also move the code for handling dynamic initialization of
method pointers from llds_out.m to rtti_out.m,
at the same time changing it to handle their new definitions
as rtti_data rather than comp_gen_c_data.
--- /tmp/fjh/mercury/compiler/llds_out.m Thu May 11 02:49:28 2000
+++ ./llds_out.m Thu May 11 02:50:42 2000
@@ -2915,21 +2915,28 @@
output_data_addr_storage_type_name(ModuleName, DataVarName, BeingDefined,
LaterIndent) -->
- { data_name_linkage(DataVarName, Linkage) },
- globals__io_get_globals(Globals),
- { c_data_linkage_string(Globals, Linkage, BeingDefined, LinkageStr) },
- io__write_string(LinkageStr),
+ ( { DataVarName = base_typeclass_info(ClassId, Instance) } ->
+ output_base_typeclass_info_storage_type_name(
+ ClassId, Instance, no)
+ ;
+ { data_name_linkage(DataVarName, Linkage) },
+ globals__io_get_globals(Globals),
+ { c_data_linkage_string(Globals, Linkage, BeingDefined,
+ LinkageStr) },
+ io__write_string(LinkageStr),
- { data_name_would_include_code_address(DataVarName, InclCodeAddr) },
- { c_data_const_string(Globals, InclCodeAddr, ConstStr) },
- io__write_string(ConstStr),
+ { data_name_would_include_code_address(DataVarName,
+ InclCodeAddr) },
+ { c_data_const_string(Globals, InclCodeAddr, ConstStr) },
+ io__write_string(ConstStr),
- io__write_string("struct "),
- output_data_addr(ModuleName, DataVarName),
- io__write_string("_struct\n"),
- io__write_string(LaterIndent),
- io__write_string("\t"),
- output_data_addr(ModuleName, DataVarName).
+ io__write_string("struct "),
+ output_data_addr(ModuleName, DataVarName),
+ io__write_string("_struct\n"),
+ io__write_string(LaterIndent),
+ io__write_string("\t"),
+ output_data_addr(ModuleName, DataVarName)
+ ).
:- pred data_name_linkage(data_name::in, linkage::out) is det.
--- /tmp/fjh/mercury/compiler/rtti_out.m Thu May 11 02:49:36 2000
+++ ./rtti_out.m Thu May 11 02:45:40 2000
@@ -23,6 +23,7 @@
:- interface.
+:- import_module hlds_data.
:- import_module rtti, llds_out.
:- import_module bool, io.
@@ -56,6 +57,11 @@
:- pred output_rtti_addr_storage_type_name(rtti_type_id::in, rtti_name::in,
bool::in, io__state::di, io__state::uo) is det.
+ % the same as output_rtti_addr_storage_type_name,
+ % but for a base_typeclass_info.
+:- pred output_base_typeclass_info_storage_type_name(class_id::in, string::in,
+ bool::in, io__state::di, io__state::uo) 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.
@@ -72,7 +78,6 @@
:- implementation.
-:- import_module hlds_data.
:- import_module pseudo_type_info, code_util, llds, prog_out, c_util.
:- import_module options, globals.
:- import_module int, string, list, require, std_util.
@@ -359,8 +364,11 @@
{ CodeAddrs = list__map(make_code_addr, Methods) },
output_code_addrs_decls(CodeAddrs, "", "", 0, _, DeclSet0, DeclSet1),
io__write_string("\n"),
- output_base_typeclass_info_decl(ClassId, InstanceString, yes,
- DeclSet1, DeclSet),
+ output_base_typeclass_info_storage_type_name(ClassId, InstanceString,
+ yes),
+ % XXX It would be nice to avoid generating redundant declarations
+ % of base_typeclass_infos, but currently we don't.
+ { DeclSet1 = DeclSet },
io__write_string(" = {\n\t(Code *) "),
io__write_list([N1, N2, N3, N4, N5], ",\n\t(Code *) ", io__write_int),
io__write_string(",\n\t"),
@@ -490,8 +498,7 @@
; { RttiData = base_typeclass_info(ClassId, InstanceStr, _) } ->
% rtti_data_to_name/3 does not handle this case
output_base_typeclass_info_decl(ClassId,
- InstanceStr, no, DeclSet0, DeclSet),
- io__write_string(";\n")
+ InstanceStr, no, DeclSet0, DeclSet)
;
{ rtti_data_to_name(RttiData, RttiTypeId, RttiName) },
output_generic_rtti_data_decl(RttiTypeId, RttiName,
@@ -504,13 +511,19 @@
output_base_typeclass_info_decl(ClassId, InstanceStr,
BeingDefined, DeclSet0, DeclSet) -->
- output_rtti_name_storage_type_name(
- output_base_typeclass_info_name(ClassId, InstanceStr),
- base_typeclass_info(ClassId, InstanceStr), BeingDefined),
- % XXX It would be nice to avoid generating multiple declarations
+ output_base_typeclass_info_storage_type_name(ClassId, InstanceStr,
+ BeingDefined),
+ io__write_string(";\n"),
+ % XXX It would be nice to avoid generating redundant declarations
% of base_typeclass_infos, but currently we don't.
{ DeclSet = DeclSet0 }.
+output_base_typeclass_info_storage_type_name(ClassId, InstanceStr,
+ BeingDefined) -->
+ output_rtti_name_storage_type_name(
+ output_base_typeclass_info_name(ClassId, InstanceStr),
+ base_typeclass_info(ClassId, InstanceStr), BeingDefined).
+
%-----------------------------------------------------------------------------%
:- pred output_generic_rtti_data_decl(rtti_type_id::in, rtti_name::in,
@@ -712,8 +725,8 @@
; { RttiData = base_typeclass_info(ClassId, InstanceStr, _) } ->
% rtti_data_to_name/3 does not handle this case,
% so we need to handle it here
- output_base_typeclass_info_decl(ClassId, InstanceStr,
- no, DeclSet0, DeclSet),
+ output_base_typeclass_info_decl(ClassId, InstanceStr, no,
+ DeclSet0, DeclSet),
{ N = N0 }
;
{ rtti_data_to_name(RttiData, RttiTypeId, RttiName) },
**********************************************************************
*** FULL DIFF ***
**********************************************************************
Index: rtti_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rtti_out.m,v
retrieving revision 1.10
diff -u -d -u -r1.10 rtti_out.m
--- rtti_out.m 2000/04/25 11:32:04 1.10
+++ rtti_out.m 2000/05/10 16:45:40
@@ -23,6 +23,7 @@
:- interface.
+:- import_module hlds_data.
:- import_module rtti, llds_out.
:- import_module bool, io.
@@ -56,6 +57,11 @@
:- pred output_rtti_addr_storage_type_name(rtti_type_id::in, rtti_name::in,
bool::in, io__state::di, io__state::uo) is det.
+ % the same as output_rtti_addr_storage_type_name,
+ % but for a base_typeclass_info.
+:- pred output_base_typeclass_info_storage_type_name(class_id::in, string::in,
+ bool::in, io__state::di, io__state::uo) 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.
@@ -74,7 +80,7 @@
:- import_module pseudo_type_info, code_util, llds, prog_out, c_util.
:- import_module options, globals.
-:- import_module string, list, require, std_util.
+:- import_module int, string, list, require, std_util.
%-----------------------------------------------------------------------------%
@@ -341,12 +347,40 @@
% io__write_string(",\n\t"),
% output_maybe_static_code_addr(Prettyprinter),
io__write_string("\n};\n").
+output_rtti_data_defn(base_typeclass_info(ClassId, InstanceString,
+ BaseTypeClassInfo), DeclSet0, DeclSet) -->
+ output_base_typeclass_info_defn(ClassId, InstanceString,
+ BaseTypeClassInfo, DeclSet0, DeclSet).
output_rtti_data_defn(pseudo_type_info(Pseudo), DeclSet0, DeclSet) -->
output_pseudo_type_info_defn(Pseudo, DeclSet0, DeclSet).
+:- pred output_base_typeclass_info_defn(class_id, string, base_typeclass_info,
+ decl_set, decl_set, io__state, io__state).
+:- mode output_base_typeclass_info_defn(in, in, in, in, out, di, uo) is det.
+
+output_base_typeclass_info_defn(ClassId, InstanceString,
+ base_typeclass_info(N1, N2, N3, N4, N5, Methods),
+ DeclSet0, DeclSet) -->
+ { CodeAddrs = list__map(make_code_addr, Methods) },
+ output_code_addrs_decls(CodeAddrs, "", "", 0, _, DeclSet0, DeclSet1),
+ io__write_string("\n"),
+ output_base_typeclass_info_storage_type_name(ClassId, InstanceString,
+ yes),
+ % XXX It would be nice to avoid generating redundant declarations
+ % of base_typeclass_infos, but currently we don't.
+ { DeclSet1 = DeclSet },
+ io__write_string(" = {\n\t(Code *) "),
+ io__write_list([N1, N2, N3, N4, N5], ",\n\t(Code *) ", io__write_int),
+ io__write_string(",\n\t"),
+ io__write_list(CodeAddrs, ",\n\t", output_static_code_addr),
+ io__write_string("\n};\n").
+
:- func make_maybe_code_addr(maybe(rtti_proc_label)) = maybe(code_addr).
make_maybe_code_addr(no) = no.
-make_maybe_code_addr(yes(ProcLabel)) = yes(CodeAddr) :-
+make_maybe_code_addr(yes(ProcLabel)) = yes(make_code_addr(ProcLabel)).
+
+:- func make_code_addr(rtti_proc_label) = code_addr.
+make_code_addr(ProcLabel) = CodeAddr :-
code_util__make_entry_label_from_rtti(ProcLabel, no, CodeAddr).
:- pred output_pseudo_type_info_defn(pseudo_type_info, decl_set, decl_set,
@@ -461,12 +495,35 @@
% so we don't need to declare them.
% Also rtti_data_to_name/3 does not handle this case.
{ DeclSet = DeclSet0 }
+ ; { RttiData = base_typeclass_info(ClassId, InstanceStr, _) } ->
+ % rtti_data_to_name/3 does not handle this case
+ output_base_typeclass_info_decl(ClassId,
+ InstanceStr, no, DeclSet0, DeclSet)
;
{ rtti_data_to_name(RttiData, RttiTypeId, RttiName) },
output_generic_rtti_data_decl(RttiTypeId, RttiName,
DeclSet0, DeclSet)
).
+:- pred output_base_typeclass_info_decl(class_id::in, string::in,
+ bool::in, decl_set::in, decl_set::out,
+ io__state::di, io__state::uo) is det.
+
+output_base_typeclass_info_decl(ClassId, InstanceStr,
+ BeingDefined, DeclSet0, DeclSet) -->
+ output_base_typeclass_info_storage_type_name(ClassId, InstanceStr,
+ BeingDefined),
+ io__write_string(";\n"),
+ % XXX It would be nice to avoid generating redundant declarations
+ % of base_typeclass_infos, but currently we don't.
+ { DeclSet = DeclSet0 }.
+
+output_base_typeclass_info_storage_type_name(ClassId, InstanceStr,
+ BeingDefined) -->
+ output_rtti_name_storage_type_name(
+ output_base_typeclass_info_name(ClassId, InstanceStr),
+ base_typeclass_info(ClassId, InstanceStr), BeingDefined).
+
%-----------------------------------------------------------------------------%
:- pred output_generic_rtti_data_decl(rtti_type_id::in, rtti_name::in,
@@ -488,6 +545,15 @@
{ decl_set_insert(DeclSet0, data_addr(DataAddr), DeclSet) }.
output_rtti_addr_storage_type_name(RttiTypeId, RttiName, BeingDefined) -->
+ output_rtti_name_storage_type_name(
+ output_rtti_addr(RttiTypeId, RttiName),
+ RttiName, BeingDefined).
+
+:- pred output_rtti_name_storage_type_name(
+ pred(io__state, io__state)::pred(di, uo) is det,
+ rtti_name::in, bool::in, io__state::di, io__state::uo) is det.
+
+output_rtti_name_storage_type_name(OutputName, RttiName, BeingDefined) -->
output_rtti_type_decl(RttiName),
{ rtti_name_linkage(RttiName, Linkage) },
globals__io_get_globals(Globals),
@@ -501,7 +567,7 @@
{ rtti_name_c_type(RttiName, CType, Suffix) },
c_util__output_quoted_string(CType),
io__write_string(" "),
- output_rtti_addr(RttiTypeId, RttiName),
+ OutputName,
io__write_string(Suffix).
:- pred output_rtti_type_decl(rtti_name::in, io__state::di, io__state::uo)
@@ -568,9 +634,37 @@
io__write_int(Arity),
io__write_string("_0);\n")
;
+ { Data = base_typeclass_info(ClassName, ClassArity,
+ base_typeclass_info(_N1, _N2, _N3, _N4, _N5,
+ Methods)) }
+ ->
+ io__write_string("#ifndef MR_STATIC_CODE_ADDRESSES\n"),
+ % the field number for the first method is 5,
+ % since the methods are stored after N1 .. N5,
+ % and fields are numbered from 0.
+ { FirstFieldNum = 5 },
+ { CodeAddrs = list__map(make_code_addr, Methods) },
+ output_init_method_pointers(FirstFieldNum, CodeAddrs,
+ ClassName, ClassArity),
+ io__write_string("#endif /* MR_STATIC_CODE_ADDRESSES */\n")
+ ;
[]
).
+:- pred output_init_method_pointers(int, list(code_addr), class_id, string,
+ io__state, io__state).
+:- mode output_init_method_pointers(in, in, in, in, di, uo) is det.
+
+output_init_method_pointers(_, [], _, _) --> [].
+output_init_method_pointers(FieldNum, [Arg|Args], ClassId, InstanceStr) -->
+ io__write_string("\t\t"),
+ io__write_string("MR_field(MR_mktag(0), "),
+ output_base_typeclass_info_name(ClassId, InstanceStr),
+ io__format(", %d) =\n\t\t\t", [i(FieldNum)]),
+ output_code_addr(Arg),
+ io__write_string(";\n"),
+ output_init_method_pointers(FieldNum + 1, Args, ClassId, InstanceStr).
+
%-----------------------------------------------------------------------------%
:- pred output_maybe_rtti_addrs_decls(rtti_type_id::in,
@@ -628,6 +722,12 @@
% Also rtti_data_to_name/3 does not handle this case.
{ DeclSet = DeclSet0 },
{ N = N0 }
+ ; { RttiData = base_typeclass_info(ClassId, InstanceStr, _) } ->
+ % rtti_data_to_name/3 does not handle this case,
+ % so we need to handle it here
+ output_base_typeclass_info_decl(ClassId, InstanceStr, no,
+ DeclSet0, DeclSet),
+ { N = N0 }
;
{ rtti_data_to_name(RttiData, RttiTypeId, RttiName) },
output_rtti_addr_decls(RttiTypeId, RttiName,
@@ -691,6 +791,9 @@
% rtti_data_to_name/3 does not handle this case
io__write_string("(MR_PseudoTypeInfo) "),
io__write_int(VarNum)
+ ; { RttiData = base_typeclass_info(ClassId, InstanceStr, _) } ->
+ % rtti_data_to_name/3 does not handle this case
+ output_base_typeclass_info_name(ClassId, InstanceStr)
;
{ rtti_data_to_name(RttiData, RttiTypeId, RttiName) },
output_addr_of_rtti_addr(RttiTypeId, RttiName)
@@ -788,11 +891,16 @@
io__state::di, io__state::uo) is det.
output_maybe_static_code_addr(yes(CodeAddr)) -->
+ output_static_code_addr(CodeAddr).
+output_maybe_static_code_addr(no) -->
+ io__write_string("NULL").
+
+:- pred output_static_code_addr(code_addr::in, io__state::di, io__state::uo)
+ is det.
+output_static_code_addr(CodeAddr) -->
io__write_string("MR_MAYBE_STATIC_CODE("),
output_code_addr(CodeAddr),
io__write_string(")").
-output_maybe_static_code_addr(no) -->
- io__write_string("NULL").
%-----------------------------------------------------------------------------%
@@ -809,6 +917,7 @@
rtti_name_would_include_code_addr(du_stag_ordered_table(_), no).
rtti_name_would_include_code_addr(du_ptag_ordered_table, no).
rtti_name_would_include_code_addr(type_ctor_info, yes).
+rtti_name_would_include_code_addr(base_typeclass_info(_, _), yes).
rtti_name_would_include_code_addr(pseudo_type_info(Pseudo),
pseudo_type_info_would_incl_code_addr(Pseudo)).
rtti_name_would_include_code_addr(type_hashcons_pointer, no).
@@ -839,6 +948,7 @@
rtti_name_c_type(du_ptag_ordered_table, "MR_DuPtagLayout", "[]").
rtti_name_c_type(type_ctor_info, "struct MR_TypeCtorInfo_Struct",
"").
+rtti_name_c_type(base_typeclass_info(_, _), "Code *", "[]").
rtti_name_c_type(pseudo_type_info(Pseudo), TypePrefix, TypeSuffix) :-
pseudo_type_info_name_c_type(Pseudo, TypePrefix, TypeSuffix).
rtti_name_c_type(type_hashcons_pointer, "union MR_TableNode_Union **", "").
Index: llds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.142
diff -u -d -u -r1.142 llds_out.m
--- llds_out.m 2000/04/26 05:40:20 1.142
+++ llds_out.m 2000/05/10 16:50:42
@@ -182,6 +182,12 @@
:- pred llds_out__make_base_typeclass_info_name(class_id, string, string).
:- mode llds_out__make_base_typeclass_info_name(in, in, out) is det.
+ % output the name for base_typeclass_info,
+ % with the appropriate "mercury_data_" prefix.
+
+:- pred output_base_typeclass_info_name(class_id, string, io__state, io__state).
+:- mode output_base_typeclass_info_name(in, in, di, uo) is det.
+
% Convert a label to a string description of the stack layout
% structure of that label.
@@ -656,14 +662,6 @@
->
rtti_out__init_rtti_data_if_nec(RttiData)
;
- { Data = comp_gen_c_data(ModuleName, DataName, _, ArgRvals,
- _, _) },
- { DataName = base_typeclass_info(_ClassName, _ClassArity) }
- ->
- io__write_string("#ifndef MR_STATIC_CODE_ADDRESSES\n"),
- output_init_method_pointers(1, ArgRvals, DataName, ModuleName),
- io__write_string("#endif /* MR_STATIC_CODE_ADDRESSES */\n")
- ;
{ Data = comp_gen_c_data(ModuleName, DataName, _, _, _, _) },
{ DataName = module_layout }
->
@@ -677,23 +675,6 @@
),
output_c_data_init_list(Datas).
-:- pred output_init_method_pointers(int, list(maybe(rval)), data_name, module_name,
- io__state, io__state).
-:- mode output_init_method_pointers(in, in, in, in, di, uo) is det.
-
-output_init_method_pointers(_, [], _, _) --> [].
-output_init_method_pointers(ArgNum, [Arg|Args], DataName, ModuleName) -->
- ( { Arg = yes(const(code_addr_const(CodeAddr))) } ->
- io__write_string("\t\t"),
- output_data_addr(ModuleName, DataName),
- io__format(".f%d =\n\t\t\t", [i(ArgNum)]),
- output_code_addr(CodeAddr),
- io__write_string(";\n")
- ;
- []
- ),
- output_init_method_pointers(ArgNum + 1, Args, DataName, ModuleName).
-
% Output a comment to tell mkinit what functions to
% call from <module>_init.c.
:- pred output_init_comment(module_name, io__state, io__state).
@@ -2934,21 +2915,28 @@
output_data_addr_storage_type_name(ModuleName, DataVarName, BeingDefined,
LaterIndent) -->
- { data_name_linkage(DataVarName, Linkage) },
- globals__io_get_globals(Globals),
- { c_data_linkage_string(Globals, Linkage, BeingDefined, LinkageStr) },
- io__write_string(LinkageStr),
+ ( { DataVarName = base_typeclass_info(ClassId, Instance) } ->
+ output_base_typeclass_info_storage_type_name(
+ ClassId, Instance, no)
+ ;
+ { data_name_linkage(DataVarName, Linkage) },
+ globals__io_get_globals(Globals),
+ { c_data_linkage_string(Globals, Linkage, BeingDefined,
+ LinkageStr) },
+ io__write_string(LinkageStr),
- { data_name_would_include_code_address(DataVarName, InclCodeAddr) },
- { c_data_const_string(Globals, InclCodeAddr, ConstStr) },
- io__write_string(ConstStr),
+ { data_name_would_include_code_address(DataVarName,
+ InclCodeAddr) },
+ { c_data_const_string(Globals, InclCodeAddr, ConstStr) },
+ io__write_string(ConstStr),
- io__write_string("struct "),
- output_data_addr(ModuleName, DataVarName),
- io__write_string("_struct\n"),
- io__write_string(LaterIndent),
- io__write_string("\t"),
- output_data_addr(ModuleName, DataVarName).
+ io__write_string("struct "),
+ output_data_addr(ModuleName, DataVarName),
+ io__write_string("_struct\n"),
+ io__write_string(LaterIndent),
+ io__write_string("\t"),
+ output_data_addr(ModuleName, DataVarName)
+ ).
:- pred data_name_linkage(data_name::in, linkage::out) is det.
@@ -3265,11 +3253,7 @@
% instance decls, even if they are in a different
% module
{ VarName = base_typeclass_info(ClassId, TypeNames) },
- { llds_out__make_base_typeclass_info_name(ClassId, TypeNames,
- Str) },
- io__write_string(mercury_data_prefix),
- io__write_string("__"),
- io__write_string(Str)
+ output_base_typeclass_info_name(ClassId, TypeNames)
;
{ VarName = module_layout },
io__write_string(mercury_data_prefix),
@@ -4230,6 +4214,12 @@
llds_out__name_mangle(TypeNames, MangledTypeNames),
string__append_list(["base_typeclass_info_", MangledClassString,
"__arity", ArityString, "__", MangledTypeNames], Str).
+
+output_base_typeclass_info_name(ClassId, TypeNames) -->
+ { llds_out__make_base_typeclass_info_name(ClassId, TypeNames, Str) },
+ io__write_string(mercury_data_prefix),
+ io__write_string("__"),
+ io__write_string(Str).
%-----------------------------------------------------------------------------%
--
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