[m-dev.] diff: fix MR_get_arg_type_info() bug

Fergus Henderson fjh at cs.mu.OZ.AU
Sat Dec 11 02:48:22 AEDT 1999


Estimated hours taken: 1.5

Fix a bug that zs reported in dgj's recent change:
MR_get_arg_type_info() was crashing on the fake type_infos
created by MR_materialize_typeinfos_base().

runtime/mercury_layout_util.c:
	Change MR_materialize_typeinfos_base() to set
	the type_ctor_info field to NULL.

runtime/mercury_type_info.c:
	Change the code for MR_get_arg_type_info() so
	that it handles the case where the type_ctor_info
	field is NULL.

Workspace: /d-drive/home/hg/public/test_mercury/test_dirs/hg/mercury
Index: runtime/mercury_layout_util.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_layout_util.c,v
retrieving revision 1.13
diff -u -d -r1.13 mercury_layout_util.c
--- runtime/mercury_layout_util.c	1999/11/05 02:32:00	1.13
+++ runtime/mercury_layout_util.c	1999/12/10 15:39:43
@@ -85,9 +85,11 @@
 		type_params = MR_NEW_ARRAY(Word, count + 1);
 
 		/*
-		** type_params should look like a typeinfo;
-		** type_params[0] is empty and will not be referred to
+		** type_params should look like a typeinfo; but
+		** type_params[0], which normally holds the type_ctor_info,
+		** will be a null pointer.
 		*/
+		type_params[0] = (Word) NULL;
 		for (i = 0; i < count; i++) {
 			if (vars->MR_slvs_tvars->MR_tp_param_locns[i] != 0) {
 				type_params[i + 1] = MR_lookup_long_lval_base(
@@ -96,11 +98,11 @@
 					saved_regs, base_sp, base_curfr,
 					&succeeded);
 				if (! succeeded) {
-					fatal_error("missing type param in MR_materialize_typeinfos_base");
+					fatal_error("missing type param in "
+					    "MR_materialize_typeinfos_base");
 				}
 			}
 		}
-
 		return type_params;
 	} else {
 		return NULL;
Index: runtime/mercury_type_info.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/mercury_type_info.c,v
retrieving revision 1.27
diff -u -d -r1.27 mercury_type_info.c
--- runtime/mercury_type_info.c	1999/12/10 14:40:38	1.27
+++ runtime/mercury_type_info.c	1999/12/10 15:44:22
@@ -130,17 +130,16 @@
 	/* 
 	** MR_create_type_info():
 	**
-	** Given a type_info (term_type_info) which contains a
-	** type_ctor_info pointer and possibly other type_infos
-	** giving the values of the type parameters of this type,
-	** and a pseudo-type_info (arg_pseudo_type_info), which contains a
-	** type_ctor_info pointer and possibly other type_infos
+	** Given a type_info `term_type_info' which contains a
+	** type_ctor_info pointer (which may be NULL) and possibly other
+	** type_infos giving the values of the type parameters of this type,
+	** and given a pseudo-type_info `arg_pseudo_type_info', which contains
+	** a type_ctor_info pointer and possibly other type_infos
 	** giving EITHER
-	** 	- the values of the type parameters of this type,
+	** 	- the values of the type parameters of this type
 	** or	- an indication of the type parameter of the
-	** 	  term_type_info that should be substituted here
-	**
-	** This returns a fully instantiated type_info, a version of the
+	** 	  term_type_info that should be substituted here,
+	** this returns a fully instantiated type_info, a version of the
 	** arg_pseudo_type_info with all the type variables filled in.
 	**
 	** We allocate memory for a new type_info on the Mercury heap,
@@ -156,6 +155,9 @@
 	** type_ctor_info. Otherwise, it is an allocated copy of a
 	** type_info.
 	**
+	** If arg_pseudo_type_info does not contain any type variables,
+	** then it is OK for term_type_info to be NULL.
+	**
 	** NOTE: If you are changing this code, you might also need
 	** to change the code in MR_make_type_info in this module 
 	** which does much the same thing, only allocating using MR_GC_malloc()
@@ -176,6 +178,11 @@
 	** In order to handle this, it also takes the data value from which
 	** the values whose pseudo type-info we are looking at was taken, as
 	** well as the functor descriptor for that functor.
+	**
+	** If the term_type_info has a NULL type_ctor_info,
+	** or if the arg_pseudo_type_info does not contain any
+	** existentially typed type variables, then it is OK
+	** for the data_value and functor_descriptor to be NULL.
 	*/
 Word * 
 MR_create_type_info_maybe_existq(const Word *term_type_info, 
@@ -262,29 +269,45 @@
 	const Word *functor_descriptor)
 {
 	Word *arg_type_info;
+	MR_TypeCtorInfo type_ctor_info;
 	int num_univ_type_infos;
+	Unsigned arg_num;
 
-	num_univ_type_infos =
-		MR_TYPEINFO_GET_TYPE_CTOR_INFO(term_type_info)->arity;
+	arg_num = (Unsigned) arg_pseudo_type_info;
 
-	if ((Word) arg_pseudo_type_info <= num_univ_type_infos) {
+	type_ctor_info = MR_TYPEINFO_GET_TYPE_CTOR_INFO(term_type_info);
+	if (type_ctor_info == NULL) {
 		/*
+		** The term_type_info is not a real type_info, it is just
+		** a vector of type_infos for the arguments with a null
+		** type_ctor_info.  Such fake type_infos are created
+		** by MR_materialize_type_infos().  For them, we treat
+		** all the type variables as being universally quantified,
+		** i.e. coming from the arg_pseudo_type_info.
+		*/
+		arg_type_info = (Word *) term_type_info[arg_num];
+		return arg_type_info;
+	}
+
+	num_univ_type_infos = type_ctor_info->arity;
+	if (arg_num <= num_univ_type_infos) {
+		/*
 		** This is a universally quantified type variable
 		*/
-		arg_type_info = (Word *) 
-			term_type_info[(Word) arg_pseudo_type_info];
+		arg_type_info = (Word *) term_type_info[arg_num];
 	} else {
 		/*
 		** This is an existentially quantified type variable
 		*/
 
+		Word *type_info_locns;
 		Word type_info_locn;
 
-		type_info_locn = ((Word *) 
+		type_info_locns = (Word *) 
 			MR_TYPE_CTOR_LAYOUT_FUNCTOR_DESCRIPTOR_TYPE_INFO_LOCNS(
-			functor_descriptor))
-				[(Integer)arg_pseudo_type_info 
-				- num_univ_type_infos - 1];
+				functor_descriptor);
+		type_info_locn =
+			type_info_locns[arg_num - num_univ_type_infos - 1];
 
 		if (MR_TYPE_INFO_LOCN_IS_INDIRECT(type_info_locn)) {
 			/*
@@ -298,21 +321,20 @@
 			typeinfo_number =
 				MR_TYPE_INFO_LOCN_INDIRECT_GET_TYPEINFO_NUMBER(
 					type_info_locn);
-
-			arg_number = MR_TYPE_INFO_LOCN_INDIRECT_GET_ARG_NUMBER(
+			arg_number =
+				MR_TYPE_INFO_LOCN_INDIRECT_GET_ARG_NUMBER(
 					type_info_locn);
-
 			arg_type_info = (Word *) MR_typeclass_info_type_info(
 				data_value[arg_number], typeinfo_number);
 		} else {
 			/*
 			** This is direct
 			*/
+			int typeinfo_number;
 
-			int typeinfo_number =
+			typeinfo_number =
 				MR_TYPE_INFO_LOCN_DIRECT_GET_TYPEINFO_NUMBER(
 					type_info_locn);
-
 			arg_type_info = (Word *) data_value[typeinfo_number];
 		}
 	}
@@ -488,18 +510,18 @@
 }
 
 	/* 
-	** Given a type_info (term_type_info) which contains a
-	** type_ctor_info pointer and possibly other type_infos
-	** giving the values of the type parameters of this type,
-	** and a pseudo-type_info (arg_pseudo_type_info), which contains a
-	** type_ctor_info pointer and possibly other type_infos
+	** Given a type_info `term_type_info' which contains a
+	** type_ctor_info pointer (which may be NULL) and possibly other
+	** type_infos giving the values of the type parameters of this type,
+	** and given a pseudo-type_info `arg_pseudo_type_info', which contains
+	** a type_ctor_info pointer and possibly other type_infos
 	** giving EITHER
 	** 	- the values of the type parameters of this type,
 	** or	- an indication of the type parameter of the
-	** 	  term_type_info that should be substituted here
-	**
-	** This returns a fully instantiated type_info, a version of the
+	** 	  term_type_info that should be substituted here,
+	** this returns a fully instantiated type_info, a version of the
 	** arg_pseudo_type_info with all the type variables filled in.
+	**
 	** If there are no type variables to fill in, we return the
 	** arg_pseudo_type_info, unchanged. Otherwise, we allocate
 	** memory using MR_GC_malloc().  Any such memory allocated will be
@@ -507,6 +529,9 @@
 	** It is the caller's responsibility to free these cells
 	** by calling MR_deallocate() on the list when they are no longer
 	** needed.
+	**
+	** If arg_pseudo_type_info does not contain any type variables,
+	** then it is OK for term_type_info to be NULL.
 	**
 	** This code could be tighter. In general, we want to
 	** handle our own allocations rather than using MR_GC_malloc().

-- 
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