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