[m-dev.] for review: cleanup of type_ctor_infos, part 2
Tyson Dowd
trd at cs.mu.OZ.AU
Sun Feb 27 15:55:44 AEDT 2000
I'm not sure whether you are aware of io__write_list or have just chosen
not to use it. Since I think it will improve the readability of the
code quite a bit to use it, I've pointed out where it would be useful.
On 25-Feb-2000, Zoltan Somogyi <zs at cs.mu.OZ.AU> wrote:
> Index: compiler/rtti.m
> ===================================================================
> RCS file: rtti.m
> diff -N rtti.m
> --- /dev/null Thu Sep 2 15:00:04 1999
> +++ rtti.m Tue Feb 22 14:12:39 2000
> @@ -0,0 +1,560 @@
> +%-----------------------------------------------------------------------------%
> +% 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.
> +%-----------------------------------------------------------------------------%
> +%
> +% Definitions of data structures for representing run-time type information
> +% within the compiler.
> +%
> +% Eventually, this module will be independent of whether we are compiling
> +% to LLDS or MLDS. For the time being, it depends on LLDS.
> +%
> +% Author: zs.
> +
> +%-----------------------------------------------------------------------------%
> +
> +:- module rtti.
> +
> +:- interface.
> +
> +:- import_module llds, prog_data.
> +:- import_module bool, list, std_util.
> +
> +:- type sectag_locn
> + ---> sectag_none
> + ; sectag_local
> + ; sectag_remote.
> +
> +:- type equality_axioms
> + ---> standard
> + ; user_defined.
These types need one line explanations.
> +
> +:- type type_ctor_layout_info
> + ---> enum_layout(
> + rtti_name
> + )
> + ; notag_layout(
> + rtti_name
> + )
> + ; du_layout(
> + rtti_name
> + )
> + ; equiv_layout(
> + rval
> + )
> + ; no_layout.
> +
> +:- type type_ctor_functors_info
> + ---> enum_functors(
> + rtti_name
> + )
> + ; notag_functors(
> + rtti_name
> + )
> + ; du_functors(
> + rtti_name
> + )
> + ; no_functors.
These types need explanations too.
> +
> +:- type exist_typeinfo_locn
> + ---> plain_typeinfo(
> + int % The typeinfo is stored
> + % directly in the cell, at this
> + % offset.
> + )
> + ; typeinfo_in_tci(
> + int, % The typeinfo is stored
> + % indirectly in the typeclass
> + % info stored at this offset
> + % in the cell.
> + int % To find the typeinfo inside
> + % the typeclass info structure,
> + % give this integer to the
> + % MR_typeclass_info_type_info
> + % macro.
> + ).
> +
> +:- type rtti_type_id
> + ---> rtti_type_id(
> + module_name, % module name
> + string, % type ctor's name
> + arity % type ctor's arity
> + ).
> +
> + % Global data generated by the compiler. Usually readonly,
> + % with one exception: data containing code addresses must
> + % be initialized.
> +:- type rtti_data
s/must/might
s/initialized/initialized at runtime in grades that don't support static
code initializers/
Also you should mention that this data corresponds to structures in
mercury_type_info.h (so they know where to look for the MR_* C types).
> + ---> exist_locns(
> + rtti_type_id, % identifies the type
> + int, % identifies functor in type
> +
> + % The remaining argument of this function symbol
> + % corresponds to an array of MR_ExistTypeInfoLocns.
> +
> + list(exist_typeinfo_locn)
> + )
> + ; exist_info(
> + rtti_type_id, % identifies the type
> + int, % identifies functor in type
> +
> + % The remaining arguments of this function symbol
> + % correspond to the MR_DuExistInfo C type.
> +
> + int, % number of plain typeinfos
> + int, % number of typeinfos in tcis
> + int, % number of tcis
> + rtti_name % table of typeinfo locations
> + )
> + ; field_names(
> + rtti_type_id, % identifies the type
> + int, % identifies functor in type
> +
> + list(maybe(string)) % gives the field names
> + )
> + ; enum_functor_desc(
> + rtti_type_id, % identifies the type
> +
> + % The remaining arguments of this function symbol
> + % correspond one-to-one to the fields of
> + % MR_EnumFunctorDesc.
s/MR_EnumFunctorDesc/the MR_EnumFunctorDesc C type/
> +
> + string, % functor name
> + int % ordinal number of functor
> + % (also its value)
> + )
> + ; notag_functor_desc(
> + rtti_type_id, % identifies the type
> +
> + % The remaining arguments of this function symbol
> + % correspond one-to-one to the fields of
> + % MR_NotagFunctorDesc.
s/MR_NotagFunctorDesc/the MR_NotagFunctorDesc C type/
> +
> + string, % functor name
> + rval % pseudo typeinfo of argument
> + )
> + ; du_functor_desc(
> + rtti_type_id, % identifies the type
> +
> + % The remaining arguments of this function symbol
> + % correspond one-to-one to the fields of
> + % MR_DuFunctorDesc.
s/MR_DuFunctorDesc/the MR_DuFunctorDesc C type/
> +:- pred rtti__make_exist_info_name(rtti_type_id::in, int::in,
> + string::out) is det.
> +
> + % Create a C variable name for the array listing the names
> + % of the fields of a function symbol.
Why are these (and the other similar functions) exported? They don't
appear to be used outside this module.
> +
> +:- pred rtti_addr_to_string(rtti_type_id::in, rtti_name::in, string::out)
> + is det.
rtti_addr should be rtti__addr.
> +
> +:- pred rtti__sectag_locn_to_string(sectag_locn::in, string::out) is det.
> +
> +:- pred rtti__type_ctor_rep_to_string(type_ctor_rep::in, string::out) is det.
> +
> +:- pred rtti__name_would_include_code_address(rtti_name::in, bool::out) is det.
These predicates need comments.
> +
> +:- implementation.
> +
> +:- import_module llds_out.
> +:- import_module string.
> +
> +rtti__make_exist_locns_name(RttiTypeId, Ordinal, Str) :-
> + RttiTypeId = rtti_type_id(ModuleName0, TypeName0, TypeArity),
> + llds_out__sym_name_mangle(ModuleName0, ModuleName),
> + llds_out__name_mangle(TypeName0, TypeName),
> + string__int_to_string(TypeArity, A_str),
> + string__int_to_string(Ordinal, O_str),
> + string__append_list([ModuleName, "__exist_locns_", TypeName,
> + "_", A_str, "_", O_str], Str).
This cut-and-paste section of code is a bit of a maintenance nightmare.
There's a lot of common code that could be factored, and a couple of
conditionals would handle the different cases. There doesn't seem to be
any reason to have each of these cases as a different predicate (if
there is, I can't seem to find it in your diff).
> +:- pred output_maybe_rtti_addrs(rtti_type_id::in, list(maybe(rtti_name))::in,
> + io__state::di, io__state::uo) is det.
> +
> +output_maybe_rtti_addrs(_, []) --> [].
> +output_maybe_rtti_addrs(RttiTypeId, [MaybeRttiName | MaybeRttiNames]) -->
> + io__write_string("\t"),
> + (
> + { MaybeRttiName = yes(RttiName) },
> + io__write_string("&"),
> + output_rtti_addr(RttiTypeId, RttiName)
> + ;
> + { MaybeRttiName = no },
> + io__write_string("NULL")
> + ),
> + (
> + { MaybeRttiNames = [] },
> + io__write_string("\n")
> + ;
> + { MaybeRttiNames = [_|_] },
> + io__write_string(",\n"),
> + output_maybe_rtti_addrs(RttiTypeId, MaybeRttiNames)
> + ).
This is a list writer.
> +:- pred output_rtti_addrs(rtti_type_id::in, list(rtti_name)::in,
> + io__state::di, io__state::uo) is det.
> +
> +output_rtti_addrs(_, []) --> [].
> +output_rtti_addrs(RttiTypeId, [RttiName | RttiNames]) -->
> + io__write_string("\t&"),
> + output_rtti_addr(RttiTypeId, RttiName),
> + (
> + { RttiNames = [] },
> + io__write_string("\n")
> + ;
> + { RttiNames = [_|_] },
> + io__write_string(",\n"),
> + output_rtti_addrs(RttiTypeId, RttiNames)
> + ).
> +
This is another list writer.
(There are quite a few other ones in this module, by converting everything to
lists of strings and io__write_list-ing them the code could be
simplified quite a bit. Most of the code converts to strings before
writing anyway).
> +output_rtti_addr(RttiTypeId, RttiName) -->
> + io__write_string(mercury_data_prefix),
> + { rtti_addr_to_string(RttiTypeId, RttiName, Str) },
> + io__write_string(Str).
> +
> +:- pred output_maybe_strings(list(maybe(string))::in,
> + io__state::di, io__state::uo) is det.
> +
> +output_maybe_strings([]) -->
> + { error("reached empty list of maybe strings") }.
> +output_maybe_strings([MaybeName | MaybeNames]) -->
> + io__write_string("\t"),
> + (
> + { MaybeName = yes(Name) },
> + io__write_string(""""),
> + io__write_string(Name),
> + io__write_string("""")
> + ;
> + { MaybeName = no },
> + io__write_string("NULL")
> + ),
> + (
> + { MaybeNames = [] },
> + io__write_string("\n")
> + ;
> + { MaybeNames = [_|_] },
> + io__write_string(",\n"),
> + output_maybe_strings(MaybeNames)
> + ).
Another one.
> +
> +:- pred output_exist_locns(list(exist_typeinfo_locn)::in,
> + io__state::di, io__state::uo) is det.
> +
> +output_exist_locns([]) -->
> + { error("reached empty list of exist locns") }.
> +output_exist_locns([Locn | Locns]) -->
> + io__write_string("\t"),
> + (
> + { Locn = plain_typeinfo(SlotInCell) },
> + io__write_string("{ "),
> + io__write_int(SlotInCell),
> + io__write_string(", -1 }")
> + ;
> + { Locn = typeinfo_in_tci(SlotInCell, SlotInTci) },
> + io__write_string("{ "),
> + io__write_int(SlotInCell),
> + io__write_string(", "),
> + io__write_int(SlotInTci),
> + io__write_string(" }")
> + ),
> + (
> + { Locns = [] },
> + io__write_string("\n")
> + ;
> + { Locns = [_|_] },
> + io__write_string(",\n"),
> + output_exist_locns(Locns)
> + ).
Another one.
Otherwise this module is fine. I think the new type for the rtti data
structures is a big improvement.
--
The quantum sort:
while (!sorted) { do_nothing(); }
Tyson Dowd <tyson at tyse.net> http://tyse.net/
--------------------------------------------------------------------------
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