[m-dev.] for review: more RTTI restructuring
Fergus Henderson
fjh at cs.mu.OZ.AU
Fri Apr 14 10:59:13 AEST 2000
Estimated hours taken: 5
Restructure the RTTI implementation to eliminate dependencies on the LLDS,
so that it can be used for the MLDS back-end as well as the LLDS back-end.
(Note that I have not yet modified the MLDS back-end to actually make
use of it; that will be a separate change.)
compiler/rtti.m:
Eliminate the dependency on LLDS, by replacing code_addr with a new
type `rtti_proc_label'. Add a procedure `rtti__make_proc_label' for
constructing these.
compiler/type_ctor_info.m:
Eliminate the dependency on LLDS, by calling rtti__make_proc_label
rather than code_util__make_entry_label.
compiler/ml_code_util.m:
Add a new procedure `ml_gen_pred_label_from_rtti',
for (eventual) use by ml_base_type_info.m.
Restructure the implementation of ml_gen_pred_label so that it
works by first calling rtti__make_proc_label and then calling
ml_gen_pred_label_from_rtti.
compiler/code_util.m:
Add new procedure `make_entry_label_from_rtti', for use by rtti_out.m.
Restructure the implementation of the predicates make_entry_label,
make_local_entry_label, and make_proc_label so that they work by first
calling rtti__make_proc_label.
compiler/rtti_out.m:
Call code_util__make_entry_label_from_rtti to
convert the rtti_proc_labels in the RTTI into code_addrs.
Workspace: /home/pgrad/fjh/ws/hg
Index: compiler/code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_util.m,v
retrieving revision 1.118
diff -u -d -r1.118 code_util.m
--- compiler/code_util.m 2000/03/15 08:30:53 1.118
+++ compiler/code_util.m 2000/04/14 00:20:53
@@ -17,12 +17,14 @@
:- interface.
-:- import_module hlds_module, hlds_pred, hlds_goal, hlds_data, prog_data, llds.
+:- import_module prog_data, hlds_module, hlds_pred, hlds_goal, hlds_data.
+:- import_module rtti, llds.
+
:- import_module list, assoc_list, set, std_util.
% Create a code address which holds the address of the specified
% procedure.
- % The fourth argument should be `no' if the the caller wants the
+ % The `immed' argument should be `no' if the the caller wants the
% returned address to be valid from everywhere in the program.
% If being valid from within the current procedure is enough,
% this argument should be `yes' wrapped around the value of the
@@ -30,10 +32,16 @@
% Using an address that is only valid from within the current
% procedure may make jumps more efficient.
+:- type immed == maybe(pair(int, pred_proc_id)).
+
:- pred code_util__make_entry_label(module_info, pred_id, proc_id,
- maybe(pair(int, pred_proc_id)), code_addr).
+ immed, code_addr).
:- mode code_util__make_entry_label(in, in, in, in, out) is det.
+:- pred code_util__make_entry_label_from_rtti(rtti_proc_label, immed,
+ code_addr).
+:- mode code_util__make_entry_label_from_rtti(in, in, out) is det.
+
% Create a label which holds the address of the specified procedure,
% which must be defined in the current module (procedures that are
% imported from other modules have representations only as code_addrs,
@@ -43,12 +51,12 @@
% code_util__make_entry_label.
:- pred code_util__make_local_entry_label(module_info, pred_id, proc_id,
- maybe(pair(int, pred_proc_id)), label).
+ immed, label).
:- mode code_util__make_local_entry_label(in, in, in, in, out) is det.
% Create a label internal to a Mercury procedure.
:- pred code_util__make_internal_label(module_info, pred_id, proc_id, int,
- label).
+ label).
:- mode code_util__make_internal_label(in, in, in, in, out) is det.
:- pred code_util__make_proc_label(module_info, pred_id, proc_id, proc_label).
@@ -150,61 +158,62 @@
:- implementation.
-:- import_module prog_data, builtin_ops, type_util, special_pred.
+:- import_module builtin_ops, type_util, special_pred.
:- import_module bool, char, int, string, set, map, term, varset.
:- import_module require, std_util, assoc_list.
%---------------------------------------------------------------------------%
-code_util__make_entry_label(ModuleInfo, PredId, ProcId, Immed, PredAddress) :-
- module_info_preds(ModuleInfo, Preds),
- map__lookup(Preds, PredId, PredInfo),
+code_util__make_entry_label(ModuleInfo, PredId, ProcId, Immed, ProcAddr) :-
+ RttiProcLabel = rtti__make_proc_label(ModuleInfo, PredId, ProcId),
+ code_util__make_entry_label_from_rtti(RttiProcLabel, Immed, ProcAddr).
+
+code_util__make_entry_label_from_rtti(RttiProcLabel, Immed, ProcAddr) :-
(
(
- pred_info_is_imported(PredInfo)
+ RttiProcLabel^is_imported = yes
;
- pred_info_is_pseudo_imported(PredInfo),
+ RttiProcLabel^is_pseudo_imported = yes,
% only the (in, in) mode of unification is imported
- hlds_pred__in_in_unification_proc_id(ProcId)
+ hlds_pred__in_in_unification_proc_id(
+ RttiProcLabel^proc_id)
)
->
- code_util__make_proc_label(ModuleInfo, PredId, ProcId,
- ProcLabel),
- PredAddress = imported(ProcLabel)
+ code_util__make_proc_label_from_rtti(RttiProcLabel, ProcLabel),
+ ProcAddr = imported(ProcLabel)
;
- code_util__make_local_entry_label(ModuleInfo, PredId, ProcId,
+ code_util__make_local_entry_label_from_rtti(RttiProcLabel,
Immed, Label),
- PredAddress = label(Label)
+ ProcAddr = label(Label)
).
code_util__make_local_entry_label(ModuleInfo, PredId, ProcId, Immed, Label) :-
- code_util__make_proc_label(ModuleInfo, PredId, ProcId, ProcLabel),
- module_info_preds(ModuleInfo, Preds),
- map__lookup(Preds, PredId, PredInfo),
+ RttiProcLabel = rtti__make_proc_label(ModuleInfo, PredId, ProcId),
+ code_util__make_local_entry_label_from_rtti(RttiProcLabel,
+ Immed, Label).
+
+:- pred code_util__make_local_entry_label_from_rtti(rtti_proc_label, immed,
+ label).
+:- mode code_util__make_local_entry_label_from_rtti(in, in, out) is det.
+
+code_util__make_local_entry_label_from_rtti(RttiProcLabel, Immed, Label) :-
+ code_util__make_proc_label_from_rtti(RttiProcLabel, ProcLabel),
(
- procedure_is_exported(PredInfo, ProcId)
- ->
- (
- Immed = no,
+ Immed = no,
+ % If we want to define the label or use it to put it
+ % into a data structure, a label that is usable only
+ % within the current C module won't do.
+ ( RttiProcLabel^is_exported = yes ->
Label = exported(ProcLabel)
;
- Immed = yes(ProcsPerFunc - proc(CurPredId, CurProcId)),
- choose_local_label_type(ProcsPerFunc, CurPredId,
- CurProcId, PredId, ProcId, ProcLabel, Label)
- )
- ;
- (
- % If we want to define the label or use it to put it
- % into a data structure, a label that is usable only
- % within the current C module won't do.
- Immed = no,
Label = local(ProcLabel)
- ;
- Immed = yes(ProcsPerFunc - proc(CurPredId, CurProcId)),
- choose_local_label_type(ProcsPerFunc, CurPredId,
- CurProcId, PredId, ProcId, ProcLabel, Label)
)
+ ;
+ Immed = yes(ProcsPerFunc - proc(CurPredId, CurProcId)),
+ choose_local_label_type(ProcsPerFunc, CurPredId, CurProcId,
+ RttiProcLabel^pred_id, RttiProcLabel^proc_id,
+ ProcLabel, Label)
).
@@ -238,14 +247,19 @@
Label = local(ProcLabel, LabelNum).
code_util__make_proc_label(ModuleInfo, PredId, ProcId, ProcLabel) :-
- module_info_pred_info(ModuleInfo, PredId, PredInfo),
- pred_info_module(PredInfo, PredModule),
- pred_info_name(PredInfo, PredName),
- module_info_name(ModuleInfo, ThisModule),
+ RttiProcLabel = rtti__make_proc_label(ModuleInfo, PredId, ProcId),
+ code_util__make_proc_label_from_rtti(RttiProcLabel, ProcLabel).
+
+:- pred code_util__make_proc_label_from_rtti(rtti_proc_label, proc_label).
+:- mode code_util__make_proc_label_from_rtti(in, out) is det.
+
+code_util__make_proc_label_from_rtti(RttiProcLabel, ProcLabel) :-
+ RttiProcLabel = rtti_proc_label(PredOrFunc, ThisModule,
+ PredModule, PredName, Arity, ArgTypes, _PredId, ProcId,
+ IsImported, _IsPseudoImported, _IsExported),
(
- code_util__compiler_generated(PredInfo)
+ special_pred_name_arity(_, _, PredName, Arity)
->
- pred_info_arg_types(PredInfo, ArgTypes),
(
special_pred_get_type(PredName, ArgTypes, Type),
type_to_type_id(Type, TypeId, _),
@@ -276,7 +290,7 @@
% Work out which module supplies the code for
% the predicate.
ThisModule \= PredModule,
- \+ pred_info_is_imported(PredInfo)
+ IsImported = no
->
% This predicate is a specialized version of
% a pred from a `.opt' file.
@@ -284,8 +298,6 @@
;
DefiningModule = PredModule
),
- pred_info_get_is_pred_or_func(PredInfo, PredOrFunc),
- pred_info_arity(PredInfo, Arity),
ProcLabel = proc(DefiningModule, PredOrFunc,
PredModule, PredName, Arity, ProcId)
).
Index: compiler/ml_code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_util.m,v
retrieving revision 1.4
diff -u -d -r1.4 ml_code_util.m
--- compiler/ml_code_util.m 2000/03/30 05:41:49 1.4
+++ compiler/ml_code_util.m 2000/04/14 00:13:11
@@ -17,6 +17,7 @@
:- import_module prog_data.
:- import_module hlds_module, hlds_pred.
+:- import_module rtti.
:- import_module mlds.
:- import_module llds. % XXX for `code_model'.
@@ -138,6 +139,10 @@
mlds__pred_label, mlds_module_name).
:- mode ml_gen_pred_label(in, in, in, out, out) is det.
+:- pred ml_gen_pred_label_from_rtti(rtti_proc_label,
+ mlds__pred_label, mlds_module_name).
+:- mode ml_gen_pred_label_from_rtti(in, out, out) is det.
+
%-----------------------------------------------------------------------------%
%
% Routines for dealing with variables
@@ -743,14 +748,17 @@
% for a given procedure.
%
ml_gen_pred_label(ModuleInfo, PredId, ProcId, MLDS_PredLabel, MLDS_Module) :-
- module_info_pred_info(ModuleInfo, PredId, PredInfo),
- pred_info_module(PredInfo, PredModule),
- pred_info_name(PredInfo, PredName),
- module_info_name(ModuleInfo, ThisModule),
+ RttiProcLabel = rtti__make_proc_label(ModuleInfo, PredId, ProcId),
+ ml_gen_pred_label_from_rtti(RttiProcLabel,
+ MLDS_PredLabel, MLDS_Module).
+
+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),
(
- code_util__compiler_generated(PredInfo)
+ special_pred_name_arity(_, _, PredName, Arity)
->
- pred_info_arg_types(PredInfo, ArgTypes),
(
special_pred_get_type(PredName, ArgTypes, Type),
type_to_type_id(Type, TypeId, _),
@@ -784,7 +792,7 @@
% Work out which module supplies the code for
% the predicate.
ThisModule \= PredModule,
- \+ pred_info_is_imported(PredInfo)
+ IsImported = no
->
% This predicate is a specialized version of
% a pred from a `.opt' file.
@@ -794,8 +802,6 @@
% that it is defined in
MaybeDeclaringModule = no
),
- pred_info_get_is_pred_or_func(PredInfo, PredOrFunc),
- pred_info_arity(PredInfo, Arity),
MLDS_PredLabel = pred(PredOrFunc, MaybeDeclaringModule,
PredName, Arity),
MLDS_Module = mercury_module_name_to_mlds(PredModule)
Index: compiler/rtti.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rtti.m,v
retrieving revision 1.3
diff -u -d -r1.3 rtti.m
--- compiler/rtti.m 2000/04/11 07:57:06 1.3
+++ compiler/rtti.m 2000/04/14 00:47:00
@@ -11,11 +11,12 @@
% The code to generate the structures is in type_ctor_info.m.
% See also pseudo_type_info.m.
%
-% Eventually, this module will be independent of whether we are compiling
-% to LLDS or MLDS. For the time being, it depends on LLDS.
-% See the XXX comment below.
+% This module is independent of whether we are compiling to LLDS or MLDS.
+% It is used as an intermediate data structure that we generate from the
+% HLDS, and which we can then convert to either LLDS or MLDS.
+% The LLDS actually incorporates this data structure unchanged.
%
-% Author: zs.
+% Authors: zs, fjh.
%-----------------------------------------------------------------------------%
@@ -23,10 +24,11 @@
:- interface.
-:- import_module llds. % XXX for code_addr, which is used in type_ctor_infos
+:- import_module hlds_module, hlds_pred.
:- import_module prog_data, pseudo_type_info.
-:- import_module list, std_util.
+:- import_module bool, list, std_util.
+
% For a given du type and a primary tag value, this says where,
% if anywhere, the secondary tag is.
:- type sectag_locn
@@ -281,11 +283,11 @@
% C type.
rtti_type_id, % identifies the type ctor
- maybe(code_addr), % unify
- maybe(code_addr), % compare
+ maybe(rtti_proc_label), % unify
+ maybe(rtti_proc_label), % compare
type_ctor_rep,
- maybe(code_addr), % solver
- maybe(code_addr), % init
+ maybe(rtti_proc_label), % solver
+ maybe(rtti_proc_label), % init
int, % RTTI version number
int, % num of ptags used if ctor_rep
% is DU or DUUSEREQ
@@ -293,7 +295,7 @@
type_ctor_functors_info,% the functor layout
type_ctor_layout_info, % the layout table
maybe(rtti_name), % the type's hash cons table
- maybe(code_addr) % prettyprinter
+ maybe(rtti_proc_label) % prettyprinter
)
; pseudo_type_info(pseudo_type_info)
.
@@ -315,6 +317,28 @@
; pseudo_type_info(pseudo_type_info)
; type_hashcons_pointer.
+ % 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).
+:- type rtti_proc_label
+ ---> rtti_proc_label(
+ pred_or_func :: pred_or_func,
+ this_module :: module_name,
+ pred_module :: module_name,
+ pred_name :: string,
+ arity :: arity,
+ arg_types :: list(type),
+ pred_id :: pred_id,
+ proc_id :: proc_id,
+ is_imported :: bool,
+ is_pseudo_imported :: bool,
+ is_exported :: bool
+ ).
+
+ % 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
@@ -337,6 +361,21 @@
:- import_module llds_out, hlds_data, type_util.
:- import_module string, require.
+rtti__make_proc_label(ModuleInfo, PredId, ProcId) = ProcLabel :-
+ module_info_name(ModuleInfo, ThisModule),
+ module_info_pred_info(ModuleInfo, PredId, PredInfo),
+ 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),
+ 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),
+ ProcLabel = rtti_proc_label(PredOrFunc, ThisModule, PredModule,
+ PredName, Arity, ArgTypes, PredId, ProcId,
+ IsImported, IsPseudoImp, IsExported).
+
rtti__addr_to_string(RttiTypeId, RttiName, Str) :-
rtti__mangle_rtti_type_id(RttiTypeId, ModuleName, TypeName, A_str),
(
@@ -434,7 +473,8 @@
string__append_list([ModuleName, "__type_info_",
TypeName, "_", A_str, ATs_str], Str)
;
- PseudoTypeInfo = higher_order_type_info(RttiTypeId, RealArity, ArgTypes),
+ PseudoTypeInfo = higher_order_type_info(RttiTypeId, RealArity,
+ ArgTypes),
rtti__mangle_rtti_type_id(RttiTypeId,
ModuleName, TypeName, _A_str),
ATs_str = pseudo_type_list_to_string(ArgTypes),
Index: compiler/rtti_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rtti_out.m,v
retrieving revision 1.7
diff -u -d -r1.7 rtti_out.m
--- compiler/rtti_out.m 2000/04/11 07:57:06 1.7
+++ compiler/rtti_out.m 2000/04/14 00:21:47
@@ -73,7 +73,8 @@
:- implementation.
-:- import_module pseudo_type_info, llds, prog_out, c_util, options, globals.
+:- import_module pseudo_type_info, code_util, llds, prog_out, c_util.
+:- import_module options, globals.
:- import_module string, list, require, std_util.
%-----------------------------------------------------------------------------%
@@ -241,9 +242,13 @@
CtorRep, Solver, Init, Version, NumPtags, NumFunctors,
FunctorsInfo, LayoutInfo, _MaybeHashCons, _Prettyprinter),
DeclSet0, DeclSet) -->
- { MaybeCodeAddrs = [Unify, Compare, Solver, Init] },
- { list__filter_map(pred(yes(CA)::in, CA::out) is semidet,
- MaybeCodeAddrs, CodeAddrs) },
+ { UnifyCA = make_maybe_code_addr(Unify) },
+ { CompareCA = make_maybe_code_addr(Compare) },
+ { SolverCA = make_maybe_code_addr(Solver) },
+ { InitCA = make_maybe_code_addr(Init) },
+ { MaybeCodeAddrs = [UnifyCA, CompareCA, SolverCA, InitCA] },
+ { CodeAddrs = list__filter_map(func(yes(CA)) = CA is semidet,
+ MaybeCodeAddrs) },
output_code_addrs_decls(CodeAddrs, "", "", 0, _, DeclSet0, DeclSet1),
output_functors_info_decl(RttiTypeId, FunctorsInfo,
DeclSet1, DeclSet2),
@@ -254,18 +259,18 @@
{ RttiTypeId = rtti_type_id(Module, Type, TypeArity) },
io__write_int(TypeArity),
io__write_string(",\n\t"),
- output_maybe_static_code_addr(Unify),
+ output_maybe_static_code_addr(UnifyCA),
io__write_string(",\n\t"),
- output_maybe_static_code_addr(Unify),
+ output_maybe_static_code_addr(UnifyCA),
io__write_string(",\n\t"),
- output_maybe_static_code_addr(Compare),
+ output_maybe_static_code_addr(CompareCA),
io__write_string(",\n\t"),
{ rtti__type_ctor_rep_to_string(CtorRep, CtorRepStr) },
io__write_string(CtorRepStr),
io__write_string(",\n\t"),
- output_maybe_static_code_addr(Solver),
+ output_maybe_static_code_addr(SolverCA),
io__write_string(",\n\t"),
- output_maybe_static_code_addr(Init),
+ output_maybe_static_code_addr(InitCA),
io__write_string(",\n\t"""),
{ prog_out__sym_name_to_string(Module, ModuleName) },
c_util__output_quoted_string(ModuleName),
@@ -339,6 +344,11 @@
io__write_string("\n};\n").
output_rtti_data_defn(pseudo_type_info(Pseudo), DeclSet0, DeclSet) -->
output_pseudo_type_info_defn(Pseudo, DeclSet0, DeclSet).
+
+:- 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) :-
+ code_util__make_entry_label_from_rtti(ProcLabel, no, CodeAddr).
:- pred output_pseudo_type_info_defn(pseudo_type_info, decl_set, decl_set,
io__state, io__state).
Index: compiler/type_ctor_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/type_ctor_info.m,v
retrieving revision 1.5
diff -u -d -r1.5 type_ctor_info.m
--- compiler/type_ctor_info.m 2000/04/11 07:57:07 1.5
+++ compiler/type_ctor_info.m 2000/04/14 00:31:14
@@ -50,7 +50,6 @@
:- implementation.
-:- import_module llds. % XXX for code_addr
:- import_module rtti, pseudo_type_info.
:- import_module hlds_data, hlds_pred, hlds_out.
:- import_module make_tags, prog_data, prog_util, prog_out.
@@ -182,11 +181,11 @@
TypeArity, _Status, HldsDefn,
MaybeUnify, MaybeCompare,
MaybeSolver, MaybeInit, MaybePretty),
- type_ctor_info__make_pred_addr(MaybeUnify, ModuleInfo, Unify),
- type_ctor_info__make_pred_addr(MaybeCompare, ModuleInfo, Compare),
- type_ctor_info__make_pred_addr(MaybeSolver, ModuleInfo, Solver),
- type_ctor_info__make_pred_addr(MaybeInit, ModuleInfo, Init),
- type_ctor_info__make_pred_addr(MaybePretty, ModuleInfo, Pretty),
+ type_ctor_info__make_proc_label(MaybeUnify, ModuleInfo, Unify),
+ type_ctor_info__make_proc_label(MaybeCompare, ModuleInfo, Compare),
+ type_ctor_info__make_proc_label(MaybeSolver, ModuleInfo, Solver),
+ type_ctor_info__make_proc_label(MaybeInit, ModuleInfo, Init),
+ type_ctor_info__make_proc_label(MaybePretty, ModuleInfo, Pretty),
module_info_globals(ModuleInfo, Globals),
globals__lookup_bool_option(Globals, type_layout, TypeLayoutOption),
@@ -212,13 +211,13 @@
TypeCtorRep, Solver, Init, Version, NumPtags, NumFunctors,
MaybeFunctors, MaybeLayout, no, Pretty).
-:- pred type_ctor_info__make_pred_addr(maybe(pred_proc_id)::in,
- module_info::in, maybe(code_addr)::out) is det.
+:- pred type_ctor_info__make_proc_label(maybe(pred_proc_id)::in,
+ module_info::in, maybe(rtti_proc_label)::out) is det.
-type_ctor_info__make_pred_addr(no, _ModuleInfo, no).
-type_ctor_info__make_pred_addr(yes(PredProcId), ModuleInfo, yes(PredAddr)) :-
+type_ctor_info__make_proc_label(no, _ModuleInfo, no).
+type_ctor_info__make_proc_label(yes(PredProcId), ModuleInfo, yes(ProcLabel)) :-
PredProcId = proc(PredId, ProcId),
- code_util__make_entry_label(ModuleInfo, PredId, ProcId, no, PredAddr).
+ ProcLabel = rtti__make_proc_label(ModuleInfo, PredId, ProcId).
%---------------------------------------------------------------------------%
--
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