[m-rev.] for review: debugging typeclass_infos
Zoltan Somogyi
zs at cs.mu.OZ.AU
Wed Jan 21 13:47:45 AEDT 2004
On 21-Jan-2004, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> I'm not sure that this helps very much, because the names "typeclass_info"
> and "base_typeclass_info" are already quite misleading -- they really
> give information about a type class instance, not a type class.
Some of the information they give, e.g. the number of superclasses, comes from
the type class declaration, not the instance declaration.
> As a result, names like "MR_typeclass_info_param_type_info" are quite
> unclear -- is it the type_info for a parameter of the instance declaration,
> or a parameter of the type class?
> Likewise for "MR_typeclass_info_num_params".
I added documentation of what the macros do, and will soon do. The updated
diff for the relevant file is added below; the only changes are in the
comments.
Zoltan.
Index: mercury_type_info.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_type_info.h,v
retrieving revision 1.108
diff -u -b -r1.108 mercury_type_info.h
--- mercury_type_info.h 23 Oct 2003 02:02:31 -0000 1.108
+++ mercury_type_info.h 21 Jan 2004 02:26:33 -0000
@@ -408,44 +408,149 @@
/*---------------------------------------------------------------------------*/
/*
-** Definitions for accessing the representation of the
-** Mercury typeclass_info.
+** Definitions for accessing typeclass_infos and base_typeclass_infos.
+** Their structure is described type_class_transformation.html in
+** compiler/notes.
+*/
+
+/*
+** Extract the base_typeclass_info from a typeclass_info.
+*/
+
+#define MR_typeclass_info_base(tci) \
+ (*(MR_Word **)(tci))
+
+/*
+** The following macros look up fields of the base_typeclass_info in the given
+** typeclass_info. These fields yield information about the instance
+** declaration from which the given typeclass_info is constructed, or about the
+** type class declaration itself.
+**
+** MR_typeclass_info_num_instance_type_vars gives the number of type variables
+** in the head of the instance declaration that aren't constrained by type
+** class constraints on the instance declaration. (Soon, this will change to
+** simply the number of type variables in the head of the instance
+** declaration.)
+**
+** MR_typeclass_info_num_instance_constraints gives the number of constraints
+** on the instance declaration.
+**
+** MR_typeclass_info_num_extra_instance_args gives the sum of
+** MR_typeclass_info_num_instance_type_vars and
+** MR_typeclass_info_num_instance_constraints.
+**
+** MR_typeclass_info_num_superclasses gives the number of typeclass constraints
+** on the typeclass declaration.
+**
+** MR_typeclass_info_num_params gives the number of parameters of the typeclass
+** declaration, which perforce is also the number of parameters of the instance
+** declaration; in other words, the arity of the type class.
*/
#define MR_typeclass_info_num_extra_instance_args(tci) \
- ((MR_Integer)(*(MR_Word **)(tci))[0])
+ ((MR_Integer) MR_typeclass_info_base(tci)[0])
#define MR_typeclass_info_num_instance_constraints(tci) \
- ((MR_Integer)(*(MR_Word **)(tci))[1])
+ ((MR_Integer) MR_typeclass_info_base(tci)[1])
#define MR_typeclass_info_num_superclasses(tci) \
- ((MR_Integer)(*(MR_Word **)(tci))[2])
-#define MR_typeclass_info_num_type_infos(tci) \
- ((MR_Integer)(*(MR_Word **)(tci))[3])
+ ((MR_Integer) MR_typeclass_info_base(tci)[2])
+#define MR_typeclass_info_num_params(tci) \
+ ((MR_Integer) MR_typeclass_info_base(tci)[3])
#define MR_typeclass_info_num_methods(tci) \
- ((MR_Integer)(*(MR_Word **)(tci))[4])
+ ((MR_Integer) MR_typeclass_info_base(tci)[4])
#define MR_typeclass_info_class_method(tci, n) \
- ((MR_Code *)(*(MR_Word **)tci)[(n+4)])
+ ((MR_Code *) MR_typeclass_info_base(tci)[(n+4)])
+
+#define MR_typeclass_info_num_instance_type_vars(tci) \
+ ( MR_typeclass_info_num_extra_instance_args(tci) \
+ - MR_typeclass_info_num_instance_constraints(tci))
/*
-** The following have the same definitions. This is because
-** the call to MR_typeclass_info_arg_typeclass_info must already
-** have the number of unconstrained type variables for the instance
-** added to it.
+** MR_typeclass_info_instance_tvar_type_info returns a typeinfo for
+** one of the type variables in the instance declaration that isn't constrained
+** by a type class constraints on the instance declaration. (Soon, this will
+** change, as above.)
+**
+** MR_typeclass_info_arg_typeclass_info returns a typeclass_info for one of the
+** constrains on the instance declaration.
+**
+** MR_typeclass_info_extra_instance_arg returns either what
+** MR_typeclass_info_instance_tvar_type_info or
+** MR_typeclass_info_arg_typeclass_info returns, depending on the value of n
+** supplied.
+**
+** Except for the sanity checks, the following macros have the same
+** definitions. This is because calls to MR_typeclass_info_arg_typeclass_info
+** must already have the number of (unconstrained) type variables in the head
+** of the instance declaration added to it.
*/
-#define MR_typeclass_info_arg_typeclass_info(tci, n) \
+
+#ifdef MR_CHECK_TYPECLASS_REFS
+ #define MR_typeclass_info_extra_instance_arg(tci, n) \
+ ((0 < (n) && (n) <= MR_typeclass_info_num_extra_instance_args(tci)) \
+ ? (((MR_Word *)(tci))[(n)]) \
+ : MR_typeclass_ref_error((tci), (n), \
+ "MR_typeclass_info_extra_instance_arg"))
+ #define MR_typeclass_info_instance_tvar_type_info(tci, n) \
+ ((0 < (n) && (n) <= MR_typeclass_info_num_instance_type_vars(tci)) \
+ ? (((MR_Word *)(tci))[(n)]) \
+ : MR_typeclass_ref_error((tci), (n), \
+ "MR_typeclass_info_instance_tvar_type_info"))
+ #define MR_typeclass_info_arg_typeclass_info(tci, n) \
+ ((MR_typeclass_info_num_instance_type_vars(tci) < (n) \
+ && (n) <= MR_typeclass_info_num_extra_instance_args(tci)) \
+ ? (((MR_Word *)(tci))[(n)]) \
+ : MR_typeclass_ref_error((tci), (n), \
+ "MR_typeclass_info_arg_typeclass_info"))
+#else
+ #define MR_typeclass_info_extra_instance_arg(tci, n) \
(((MR_Word *)(tci))[(n)])
-#define MR_typeclass_info_unconstrained_type_info(tci, n) \
+ #define MR_typeclass_info_instance_tvar_type_info(tci, n) \
(((MR_Word *)(tci))[(n)])
+ #define MR_typeclass_info_arg_typeclass_info(tci, n) \
+ (((MR_Word *)(tci))[(n)])
+#endif
/*
-** The following have the same definitions. This is because
-** the call to MR_typeclass_info_type_info must already have the
-** number of superclass_infos for the class added to it.
+** MR_typeclass_info_superclass_info return a typeclass_info for one of the
+** constraints on the typeclass declaration, i.e. for one this class's
+** superclasses.
+**
+** MR_typeclass_info_param_type_info returns a typeinfo for one the types
+** to which the type class constraint applies, i.e. for one of the types bound
+** to the type variables in the head of the type class declaration.
+**
+** Except for the sanity checks, the following macros have the same
+** definitions. This is because calls to MR_typeclass_info_param_type_info
+** must already have the number of superclasses for the class added to it.
*/
-#define MR_typeclass_info_superclass_info(tci, n) \
+#ifdef MR_CHECK_TYPECLASS_REFS
+ #define MR_typeclass_info_superclass_info(tci, n) \
+ ((0 < (n) && (n) <= MR_typeclass_info_num_superclasses(tci)) \
+ ? (((MR_Word *)(tci))[ \
+ MR_typeclass_info_num_extra_instance_args(tci) + (n)]) \
+ : MR_typeclass_ref_error((tci), (n), "MR_typeclass_info_superclass_info"))
+ #define MR_typeclass_info_param_type_info(tci, n) \
+ ((MR_typeclass_info_num_superclasses(tci) < (n) \
+ && ((n) - MR_typeclass_info_num_superclasses(tci)) \
+ <= MR_typeclass_info_num_params(tci)) \
+ ? (((MR_Word *)(tci))[ \
+ MR_typeclass_info_num_extra_instance_args(tci) + (n)]) \
+ : MR_typeclass_ref_error((tci), (n), "MR_typeclass_info_param_type_info"))
+#else
+ #define MR_typeclass_info_superclass_info(tci, n) \
(((MR_Word *)(tci))[MR_typeclass_info_num_extra_instance_args(tci) + (n)])
-#define MR_typeclass_info_type_info(tci, n) \
+ #define MR_typeclass_info_param_type_info(tci, n) \
(((MR_Word *)(tci))[MR_typeclass_info_num_extra_instance_args(tci) + (n)])
+#endif
+
+/*
+** Report an attempt to access a typeclass_info with incorrect parameters,
+** and abort. MR_typeclass_ref_error doesn't return; the return value is there
+** only to appease the C typechecker.
+*/
+
+extern MR_Word MR_typeclass_ref_error(MR_Word tci, int n, const char *msg);
/*---------------------------------------------------------------------------*/
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list