type_info bug fix

Fergus Henderson fjh at cs.mu.oz.au
Fri Feb 28 06:31:10 AEDT 1997


Hi Tyson,

Can you please review this?

I think the following patch will fix the bug that caused
tests/hard_coded/ho_soln.m to crash in certain grades on kryten.
I haven't tested it yet, but I will do so before committing it.

The bugs were

	- OFFSET_FOR_ARG_TYPE_INFOS was wrong when using
	  shared-one-or-two-cell type_infos.

	- the two defitions of TYPEINFO_OFFSET_FOR_PRED_ARGS
	  for with/without shared-one-or-two-cell type_infos
	  were swapped.

Incidentally, Tyson, although I am now reasonably confident that the
other TYPEINFO_OFFSET_FOR_... macros are correct, I don't trust the
TYPELAYOUT_..._OFFSET macros.  I tried to verify that they had values
which matched the documentation in compiler/base_type_layout.m, but
the correspondence between the two is not obvious and it is quite
difficult to verify that the values are correct.  Could you please
(a) carefully check the the values are indeed correct, and (b)
improve the documentation and/or structure of the code to make it
more obvious that they are correct?

runtime/type_info.h:
	Fix some bugs in the definitions of the offsets for the
	type_info structure.  Reorganize some of the code with
	the aim of making it a bit more maintainable: the #defines
	now define the different offsets in ascending numerical order,
	so any similar mistakes in future should stick out a bit more.
	Also make sure that values are only defined if they will
	be meaningful (e.g. don't define OFFSET_FOR_TYPE_TO_TERM
	if USE_TYPE_TO_TERM is not defined); that will catch attempts
	to use bogus values.

runtime/call.mod:
	Use USE_TYPE_TO_TERM rather than hard-coding the expected value of
	OFFSET_FOR_ARG_TYPEINFOS.  Also indent the `#if's to make it a bit
	more readable.

compiler/polymorphism.m:
	Add a reminder to change run the #defines in runtime/type_info.h
	if the documentation here is changed, and vice versa.
	Also a few other minor implements to the documentation.

Index: type_info.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/type_info.h,v
retrieving revision 1.20
diff -u -r1.20 type_info.h
--- type_info.h	1997/02/23 01:14:20	1.20
+++ type_info.h	1997/02/27 18:34:48
@@ -48,38 +48,56 @@
 /*---------------------------------------------------------------------------*/
 
 /*
-** Define offsets of fields in the type_info structure.
+** Define offsets of fields in the base_type_info or type_info structure.
+** If ONE_OR_TWO_CELL_TYPE_INFO, these are offsets into the base_type_info,
+** otherwise they are offsets into the type_info.
 ** See polymorphism.m for explanation of these offsets and how the
-** type_info structure is laid out.
+** type_info and base_type_info structures are laid out.
+**
+** ANY CHANGES HERE MUST BE MATCHED BY CORRESPONDING CHANGES
+** TO THE DOCUMENTATION IN compiler/polymorphism.m.
+**
+** Note that USE_TYPE_TO_TERM is presently undefined. Code may break if it
+** is just redefined here - changes also need to be made to the compiler.
 **
 ** The one_or_two_cell type_info representation
 ** *depends* on OFFSET_FOR_COUNT being 0.
 */
-
-
 #define OFFSET_FOR_COUNT 0
 #define OFFSET_FOR_UNIFY_PRED 1
 #define OFFSET_FOR_INDEX_PRED 2
 #define OFFSET_FOR_COMPARE_PRED 3
-#define OFFSET_FOR_TERM_TO_TYPE_PRED 4
-#define OFFSET_FOR_TYPE_TO_TERM_PRED 5
-
+#ifdef USE_TYPE_TO_TERM
+  #define OFFSET_FOR_TERM_TO_TYPE_PRED 4
+  #define OFFSET_FOR_TYPE_TO_TERM_PRED 5
+#else
+  /* tough luck, those are only defined if USE_TYPE_TO_TERM is set */
+#endif
+#ifdef ONE_OR_TWO_CELL_TYPE_INFO
+  #ifdef USE_TYPE_TO_TERM
+    #define OFFSET_FOR_BASE_TYPE_LAYOUT 6
+    #define OFFSET_FOR_BASE_TYPE_FUNCTORS 7
+    #define OFFSET_FOR_TYPE_NAME 8
+  #else
+    #define OFFSET_FOR_BASE_TYPE_LAYOUT 4
+    #define OFFSET_FOR_BASE_TYPE_FUNCTORS 5
+    #define OFFSET_FOR_TYPE_NAME 6
+  #endif
+#else
+  /* tough luck, those are only defined for one-or-two-cell type_infos */
+#endif
 
-/* 
-** USE_TYPE_TO_TERM is presently undefined. Code may break if it is
-** just redefined here - changes also need to be made to the compiler.
+/*
+** Define offsets of fields in the type_info structure.
 */
-
-#ifdef USE_TYPE_TO_TERM
-	#define OFFSET_FOR_ARG_TYPE_INFOS 6 
-	#define OFFSET_FOR_BASE_TYPE_LAYOUT 6 
-	#define OFFSET_FOR_BASE_TYPE_FUNCTORS 7 
-	#define OFFSET_FOR_TYPE_NAME 8
-#else
-	#define OFFSET_FOR_ARG_TYPE_INFOS 4
-	#define OFFSET_FOR_BASE_TYPE_LAYOUT 4
-	#define OFFSET_FOR_BASE_TYPE_FUNCTORS 5
-	#define OFFSET_FOR_TYPE_NAME 6
+#ifdef ONE_OR_TWO_CELL_TYPE_INFO
+  #define OFFSET_FOR_ARG_TYPE_INFOS 1
+#else
+  #ifdef USE_TYPE_TO_TERM
+    #define OFFSET_FOR_ARG_TYPE_INFOS 6
+  #else
+    #define OFFSET_FOR_ARG_TYPE_INFOS 4
+  #endif
 #endif
 
 /*
@@ -93,10 +111,10 @@
 
 #ifdef ONE_OR_TWO_CELL_TYPE_INFO
 	#define TYPEINFO_OFFSET_FOR_PRED_ARITY 1
-	#define TYPEINFO_OFFSET_FOR_PRED_ARGS OFFSET_FOR_ARG_TYPE_INFOS
+	#define TYPEINFO_OFFSET_FOR_PRED_ARGS 2
 #else
 	#define TYPEINFO_OFFSET_FOR_PRED_ARITY OFFSET_FOR_COUNT
-	#define TYPEINFO_OFFSET_FOR_PRED_ARGS 2
+	#define TYPEINFO_OFFSET_FOR_PRED_ARGS OFFSET_FOR_ARG_TYPE_INFOS
 #endif
 
 /*---------------------------------------------------------------------------*/
@@ -286,7 +304,7 @@
 #define TYPELAYOUT_MAX_VARINT		1024
 
 /*
-** Offsets for functors and arities.
+** Offsets into the type_layout structure for functors and arities.
 **
 ** Constant and enumeration values start at 0, so the functor
 ** is at OFFSET + const/enum value. 
Index: call.mod
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/call.mod,v
retrieving revision 1.26
diff -u -r1.26 call.mod
--- call.mod	1997/02/12 07:42:32	1.26
+++ call.mod	1997/02/27 19:12:22
@@ -517,7 +517,7 @@
 
 mercury__term_to_type_2_0:
 {
-#if OFFSET_FOR_ARG_TYPE_INFOS != 6
+#ifndef USE_TYPE_TO_TERM
 	fatal_error("type_to_term/2 and term_to_type/2 not implemented");
 #else
 
@@ -529,7 +529,7 @@
 	Word	term;
 	int	i;
 
-#ifdef	ONE_OR_TWO_CELL_TYPE_INFO
+  #ifdef ONE_OR_TWO_CELL_TYPE_INFO
 	Word	base_type_info;
 
 	term = mercury__term_to_type__term;
@@ -547,7 +547,7 @@
 				OFFSET_FOR_TERM_TO_TYPE_PRED);
 		args_base = mercury__term_to_type__typeinfo;
 	}
-#else
+  #else /* not ONE_OR_TWO_CELL_TYPE_INFO */
 	term = mercury__term_to_type__term;
 
 	type_arity = field(0, mercury__term_to_type__typeinfo,
@@ -557,7 +557,7 @@
 			OFFSET_FOR_TERM_TO_TYPE_PRED);
 	args_base = (Word) ((Word *) mercury__term_to_type__typeinfo
 			- 1 + OFFSET_FOR_ARG_TYPE_INFOS);
-#endif
+  #endif /* not ONE_OR_TWO_CELL_TYPE_INFO */
 
 	save_registers();
 
@@ -570,15 +570,15 @@
 
 	restore_registers();
 
-#ifdef	COMPACT_ARGS
+  #ifdef COMPACT_ARGS
 	tailcall(term_to_type_pred, LABEL(mercury__term_to_type_2_0));
-#else
+  #else
 	push(succip);
 	push(type_arity);
 	call(term_to_type_pred, LABEL(mercury__term_to_type_2_0_i1),
 		LABEL(mercury__term_to_type_2_0));
-#endif
-#endif
+  #endif /* not COMPACT_ARGS */
+#endif /* USE_TYPE_TO_TERM */
 }
 /*
 ** Since mod2c declares this label, we must define it,
@@ -586,12 +586,13 @@
 */
 mercury__term_to_type_2_0_i1:
 {
-#if OFFSET_FOR_ARG_TYPE_INFOS != 6
+#ifndef USE_TYPE_TO_TERM
 	fatal_error("type_to_term/2 and term_to_type/2 not implemented");
 #else
-#ifdef	COMPACT_ARGS
-	fatal_error("mercury__term_to_type_2_0_i1 reached in COMPACT_ARGS mode");
-#else
+  #ifdef COMPACT_ARGS
+	fatal_error("mercury__term_to_type_2_0_i1 reached in "
+		"COMPACT_ARGS mode");
+  #else
 	/* r1 already contains the truth result of the semidet pred */
 	/* mercury__term_to_type_2_0 so r1 does not have to be updated. */
 
@@ -602,8 +603,8 @@
 	save_registers();
 	r4 = virtual_reg(type_arity + 3);
 	proceed();
-#endif
-#endif
+  #endif /* not COMPACT_ARGS */
+#endif /* USE_TYPE_TO_TERM */
 }
 
 /*
@@ -627,7 +628,7 @@
 
 mercury__type_to_term_2_0:
 {
-#if OFFSET_FOR_ARG_TYPE_INFOS != 6
+#ifndef USE_TYPE_TO_TERM
 	fatal_error("type_to_term/2 and term_to_type/2 not implemented");
 #else
 
@@ -639,7 +640,7 @@
 	Word	x;
 	int	i;
 
-#ifdef	ONE_OR_TWO_CELL_TYPE_INFO
+  #ifdef ONE_OR_TWO_CELL_TYPE_INFO
 	Word	base_type_info;
 
 	x = r2;
@@ -656,13 +657,13 @@
 				OFFSET_FOR_TYPE_TO_TERM_PRED);
 		args_base = r1;
 	}
-#else
+  #else /* not ONE_OR_TWO_CELL_TYPE_INFO */
 	x = r2;
 
 	type_arity = field(0, r1, OFFSET_FOR_COUNT);
 	type_to_term_pred = (Code *) field(0, r1, OFFSET_FOR_TYPE_TO_TERM_PRED);
 	args_base = (Word) ((Word *) r1 - 1 + OFFSET_FOR_ARG_TYPE_INFOS);
-#endif
+  #endif /* not ONE_OR_TWO_CELL_TYPE_INFO */
 
 	save_registers();
 
@@ -674,15 +675,15 @@
 
 	restore_registers();
 
-#ifdef	COMPACT_ARGS
+  #ifdef COMPACT_ARGS
 	tailcall(type_to_term_pred, LABEL(mercury__type_to_term_2_0));
-#else
+  #else /* not COMPACT_ARGS */
 	push(succip);
 	push(type_arity);
 	call(type_to_term_pred, LABEL(mercury__type_to_term_2_0_i1),
 		LABEL(mercury__type_to_term_2_0));
-#endif
-#endif
+  #endif /* not COMPACT_ARGS */
+#endif /* USE_TYPE_TO_TERM */
 }
 /*
 ** Since mod2c declares this label, we must define it,
@@ -690,12 +691,13 @@
 */
 mercury__type_to_term_2_0_i1:
 {
-#if OFFSET_FOR_ARG_TYPE_INFOS != 6
+#ifndef USE_TYPE_TO_TERM
 	fatal_error("type_to_term/2 and term_to_type/2 not implemented");
 #else
-#ifdef	COMPACT_ARGS
-	fatal_error("mercury__type_to_term_2_0_i1 reached in COMPACT_ARGS mode");
-#else
+  #ifdef COMPACT_ARGS
+	fatal_error("mercury__type_to_term_2_0_i1 reached in "
+		"COMPACT_ARGS mode");
+  #else
 	int	type_arity;
 	
 	type_arity = pop();
@@ -703,7 +705,7 @@
 	save_registers();
 	r3 = virtual_reg(type_arity + 2);
 	proceed();
-#endif
+  #endif
 #endif
 }
 
Index: polymorphism.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/polymorphism.m,v
retrieving revision 1.98
diff -u -r1.98 polymorphism.m
--- polymorphism.m	1997/02/23 06:07:37	1.98
+++ polymorphism.m	1997/02/27 18:16:53
@@ -27,6 +27,10 @@
 %
 % Representation of type information:
 %
+% IMPORTANT: ANY CHANGES TO THE DOCUMENTATION HERE MUST BE REFLECTED BY
+% SIMILAR CHANGES TO THE #defines IN "runtime/type_info.h"
+% AND VICE VERSA.
+%
 % We can use one of two ways to represent the type information.
 %
 % The old way has one cell, the type_info structure, laid out like this:
@@ -36,6 +40,10 @@
 %	word 1		<=/2 predicate for type>
 %	word 2		<index/2 predicate for type>
 %	word 3		<compare/3 predicate for type>
+%	word 4+		<the type_infos for the type params, if any>
+%
+%	or if using type_to_term predicates:
+%
 %	word 4		<term_to_type/2 predicate for type>
 %	word 5		<type_to_term/2 predicate for type>
 %	word 6+		<the type_infos for the type params, if any>
@@ -51,8 +59,8 @@
 %	word 4		<base_type_layout for type>
 %	word 5		<base_type_functors for type>
 %	word 6		<string name of type>
-%			e.g. "int" for 'int', "list" for 'list(T),
-%			"map" for 'map(K,V)'
+%			e.g. "int" for `int', "list" for `list(T)',
+%			"map" for `map(K,V)'
 %
 %	or if using type_to_term predicates:
 %
@@ -67,7 +75,7 @@
 %	word 0		<pointer to the base_type_info structure>
 %	word 1+		<the type_infos for the type params, at least one>
 %
-%	(seen note below for how higher order types differ)
+%	(but see note below for how higher order types differ)
 %
 %-----------------------------------------------------------------------------%
 %
@@ -816,7 +824,7 @@
 		% predicate for type T.  We just pass a dummy value (0).
 		%
 		%	:- pred p.
-		%	:- pred q(T, pred(T, T)).
+		%	:- pred q(type_info(T), list(T)).
 		%	p :- q(0, []).
 		%
 		% (This isn't really type-correct, but we're already past

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



More information about the developers mailing list