[m-rev.] for review: reserved address data representation (part 2)

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Oct 24 14:38:14 AEST 2001


On 24-Oct-2001, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> Allow the compiler to optionally make use of reserved addresses --
> null pointers, ints cast to pointers, and addresses of global variables --
> to optimize the representation of constants in discriminated union types.

Estimated hours taken: 18
Branches: main

Add RTTI support for the new reserved address data representations.

runtime/mercury_type_info.h:
runtime/mercury_mcpp.h:
runtime/mercury.h:
library/private_builtin.m:
library/rtti_implementation.m:
	Add MR_TYPECTOR_REP_RESERVED_ADDR (with and without _USEREQ) to
	the MR_TypeCtorRep enum, for discriminated union types containing
	one or more functors represented using reserved addresses,
	and add new RTTI structs to hold information about how such
	types are represented.
	
compiler/type_ctor_info.m:
compiler/mlds_to_gcc.m:
compiler/opt_debug.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
	Add appropriate code to generate these new RTTI structs.

runtime/mercury_deep_copy_body.h:
runtime/mercury_ml_expand_body.h:
runtime/mercury_unify_compare_body.h:
runtime/mercury_tabling.c:
library/std_util.m:
	Add code to handle the MR_TYPECTOR_REP_RESERVED_ADDR alternative,
	using the information in the new RTTI structs.

Workspace: /home/earth/fjh/ws-earth2/mercury
Index: runtime/mercury_type_info.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_type_info.h,v
retrieving revision 1.74
diff -u -d -r1.74 mercury_type_info.h
--- runtime/mercury_type_info.h	17 Aug 2001 10:15:47 -0000	1.74
+++ runtime/mercury_type_info.h	22 Oct 2001 12:10:37 -0000
@@ -551,6 +551,8 @@
     MR_DEFINE_BUILTIN_ENUM_CONST(MR_TYPECTOR_REP_NOTAG_GROUND_USEREQ),
     MR_DEFINE_BUILTIN_ENUM_CONST(MR_TYPECTOR_REP_EQUIV_GROUND),
     MR_DEFINE_BUILTIN_ENUM_CONST(MR_TYPECTOR_REP_TUPLE),
+    MR_DEFINE_BUILTIN_ENUM_CONST(MR_TYPECTOR_REP_RESERVED_ADDR),
+    MR_DEFINE_BUILTIN_ENUM_CONST(MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ),
     /*
     ** MR_TYPECTOR_REP_UNKNOWN should remain the last alternative;
     ** MR_TYPE_CTOR_STATS depends on this.
@@ -606,7 +608,9 @@
     || ((rep) == MR_TYPECTOR_REP_NOTAG)                     \
     || ((rep) == MR_TYPECTOR_REP_NOTAG_USEREQ)              \
     || ((rep) == MR_TYPECTOR_REP_NOTAG_GROUND)              \
-    || ((rep) == MR_TYPECTOR_REP_NOTAG_GROUND_USEREQ))
+    || ((rep) == MR_TYPECTOR_REP_NOTAG_GROUND_USEREQ)       \
+    || ((rep) == MR_TYPECTOR_REP_RESERVED_ADDR)             \
+    || ((rep) == MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ))
 
 /*
 ** Returns TRUE if the type_ctor_info is used to represent
@@ -781,6 +785,14 @@
 
 /*---------------------------------------------------------------------------*/
 
+typedef struct {
+    MR_ConstString      MR_ra_functor_name;
+    MR_int_least32_t    MR_ra_functor_ordinal;
+    const void 		*MR_ra_functor_reserved_addr;
+} MR_ReservedAddrFunctorDesc;
+
+/*---------------------------------------------------------------------------*/
+
 /*
 ** This type describes the function symbols that share the same primary tag.
 ** The sharers field gives their number, and thus also the size
@@ -840,6 +852,45 @@
 /*---------------------------------------------------------------------------*/
 
 /*
+** This type is used to describe the representation of discriminated unions
+** where one or more constants in the discriminated union are represented
+** using reserved addresses.
+*/
+
+typedef struct {
+    /*
+    ** The number of different reserved numeric addresses.
+    ** The actual numeric addresses reserved will range from 0 (NULL)
+    ** to one less than the value of this field.
+    */
+    MR_int_least16_t    MR_ra_num_res_numeric_addrs;
+
+    /*
+    ** The number of different reserved symbolic addresses,
+    ** and their corresponding values.
+    */
+    MR_int_least16_t    MR_ra_num_res_symbolic_addrs;
+    const void * const *MR_ra_res_symbolic_addrs;
+
+    /*
+    ** The functor descriptors for any constants represented with reserved
+    ** addresses.  Those with numeric addresses precede those with
+    ** symbolic addresses.
+    */
+    const MR_ReservedAddrFunctorDesc * const * MR_ra_constants;
+
+    /*
+    ** The representation of the remaining functors in the type.
+    */
+    MR_DuTypeLayout	MR_ra_other_functors;  
+
+} MR_ReservedAddrTypeDesc;
+
+typedef MR_ReservedAddrTypeDesc *MR_ReservedAddrTypeLayout;
+
+/*---------------------------------------------------------------------------*/
+
+/*
 ** This type describes the identity of the type that an equivalence type
 ** is equivalent to, and hence its layout.
 **
@@ -873,8 +924,8 @@
 
 /*
 ** This type describes the layout in any kind of discriminated union
-** type: du, enum and notag. In an equivalence type, it gives the identity
-** of the equivalent-to type.
+** type: du, enum, notag, or reserved_addr.
+** In an equivalence type, it gives the identity of the equivalent-to type.
 ** 
 ** The layout_init alternative is used only for static initializers,
 ** because ANSI C89 does not allow you to say which member of a union
@@ -883,11 +934,12 @@
 */
 
 typedef union {
-    void                *layout_init;
-    MR_DuTypeLayout     layout_du;
-    MR_EnumTypeLayout   layout_enum;
-    MR_NotagTypeLayout  layout_notag;
-    MR_EquivLayout      layout_equiv;
+    void                	*layout_init;
+    MR_DuTypeLayout     	layout_du;
+    MR_EnumTypeLayout   	layout_enum;
+    MR_NotagTypeLayout  	layout_notag;
+    MR_ReservedAddrTypeLayout	layout_reserved_addr;
+    MR_EquivLayout      	layout_equiv;
 } MR_TypeLayout;
 
 /*---------------------------------------------------------------------------*/
Index: runtime/mercury.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury.h,v
retrieving revision 1.37
diff -u -d -r1.37 mercury.h
--- runtime/mercury.h	31 May 2001 06:00:10 -0000	1.37
+++ runtime/mercury.h	22 Oct 2001 16:11:53 -0000
@@ -168,6 +168,8 @@
 typedef const MR_DuFunctorDesc *	MR_DuFunctorDescPtr;
 typedef union MR_TableNode_Union * *	MR_TableNodePtrPtr;
 typedef MR_Box				MR_BaseTypeclassInfo;
+typedef const void * const *		MR_ReservedAddrs;
+typedef const MR_ReservedAddrFunctorDesc *MR_ReservedAddrFunctors;
 
 
 /*
Index: runtime/mercury_deep_copy_body.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_deep_copy_body.h,v
retrieving revision 1.38
diff -u -d -r1.38 mercury_deep_copy_body.h
--- runtime/mercury_deep_copy_body.h	7 Aug 2001 23:12:25 -0000	1.38
+++ runtime/mercury_deep_copy_body.h	22 Oct 2001 12:12:53 -0000
@@ -34,9 +34,10 @@
 copy(maybeconst MR_Word *data_ptr, MR_TypeInfo type_info,
     const MR_Word *lower_limit, const MR_Word *upper_limit)
 {
-    MR_Word                data;
-    MR_Word                new_data;
+    MR_Word             data;
+    MR_Word             new_data;
     MR_TypeCtorInfo     type_ctor_info;
+    MR_DuTypeLayout     du_type_layout;
 
     data = *data_ptr;
 
@@ -50,15 +51,57 @@
         new_data = data;    /* just a copy of the actual item */
         break;
 
+    case MR_TYPECTOR_REP_RESERVED_ADDR:
+    case MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ:
+	{
+	    int j;
+	    MR_ReservedAddrTypeLayout ra_layout =
+		    	type_ctor_info->type_layout.layout_reserved_addr;
+
+	    /*
+	    ** First check if this value is one of
+	    ** the numeric reserved addresses.
+	    */
+	    if ((MR_Unsigned) data <
+		(MR_Unsigned) ra_layout->MR_ra_num_res_numeric_addrs)
+	    {
+		new_data = data;
+		break;
+	    }
+
+	    /*
+	    ** Next check if this value is one of the
+	    ** the symbolic reserved addresses.
+	    */
+	    for (j = 0; j < ra_layout->MR_ra_num_res_symbolic_addrs; j++) {
+	        if (data == (MR_Word) ra_layout->MR_ra_res_symbolic_addrs[j]) {
+		   new_data = data;
+		   /* "break" here would just exit the "for" loop */
+		   return new_data;
+		}
+	    }
+		
+	    /*
+	    ** Otherwise, it is not one of the reserved addresses,
+	    ** so handle it like a normal DU type.
+	    */
+	    du_type_layout = ra_layout->MR_ra_other_functors;
+	    goto du_type;
+	}
+
     case MR_TYPECTOR_REP_DU:
     case MR_TYPECTOR_REP_DU_USEREQ:
+    	du_type_layout = type_ctor_info->type_layout.layout_du;
+	/* fallthru */
+
+    du_type:
         {
-            MR_DuPtagLayout     *ptag_layout;
-            int                 ptag;
             MR_Word                *data_value;
+	    MR_DuPtagLayout     *ptag_layout;
+	    int                 ptag;
 
             ptag = MR_tag(data);
-            ptag_layout = &type_ctor_info->type_layout.layout_du[ptag];
+            ptag_layout = &du_type_layout[ptag];
 
             switch (ptag_layout->MR_sectag_locn) {
             case MR_SECTAG_LOCAL:
Index: runtime/mercury_mcpp.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_mcpp.h,v
retrieving revision 1.11
diff -u -d -r1.11 mercury_mcpp.h
--- runtime/mercury_mcpp.h	16 Aug 2001 15:04:14 -0000	1.11
+++ runtime/mercury_mcpp.h	22 Oct 2001 11:05:49 -0000
@@ -154,6 +154,8 @@
 #define MR_TYPECTOR_REP_NOTAG_GROUND_USEREQ_val		28
 #define MR_TYPECTOR_REP_EQUIV_GROUND_val		29
 #define MR_TYPECTOR_REP_TUPLE_val			30
+#define MR_TYPECTOR_REP_RESERVED_ADDR_val		31
+#define MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ_val	32
 
 // XXX we should integrate this macro in with the version in 
 // mercury_typeinfo.h
Index: runtime/mercury_ml_expand_body.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_ml_expand_body.h,v
retrieving revision 1.2
diff -u -d -r1.2 mercury_ml_expand_body.h
--- runtime/mercury_ml_expand_body.h	12 Jul 2001 01:30:30 -0000	1.2
+++ runtime/mercury_ml_expand_body.h	22 Oct 2001 12:55:52 -0000
@@ -176,6 +176,7 @@
     EXPAND_TYPE_NAME *expand_info)
 {
     MR_TypeCtorInfo type_ctor_info;
+    MR_DuTypeLayout du_type_layout;
 
     type_ctor_info = MR_TYPEINFO_GET_TYPE_CTOR_INFO(type_info);
     expand_info->non_canonical_type = FALSE;
@@ -198,11 +199,64 @@
             handle_zero_arity_args();
             break;
 
+        case MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ:
+            expand_info->non_canonical_type = TRUE;
+	    /* fall through */
+
+        case MR_TYPECTOR_REP_RESERVED_ADDR:
+	    {
+		int i;
+                MR_Word data;
+		MR_ReservedAddrTypeLayout ra_layout;
+
+		ra_layout = type_ctor_info->type_layout.layout_reserved_addr;
+		data = *data_word_ptr;
+
+		/*
+		** First check if this value is one of
+		** the numeric reserved addresses.
+		*/
+		if ((MR_Unsigned) data <
+		    (MR_Unsigned) ra_layout->MR_ra_num_res_numeric_addrs)
+		{
+		    handle_functor_name(ra_layout->MR_ra_constants[data]->
+			    	MR_ra_functor_name);
+		    handle_zero_arity_args();
+		    break;
+		}
+
+		/*
+		** Next check if this value is one of the
+		** the symbolic reserved addresses.
+		*/
+		for (i = 0; i < ra_layout->MR_ra_num_res_symbolic_addrs; i++) {
+		    if (data == (MR_Word) ra_layout->MR_ra_res_symbolic_addrs[i]) {
+			int offset = i + ra_layout->MR_ra_num_res_numeric_addrs;
+		    	handle_functor_name(ra_layout->MR_ra_constants[offset]->
+					MR_ra_functor_name);
+		    	handle_zero_arity_args();
+		    	/* "break" here would just exit the "for" loop */
+		    	return;
+		    }
+		}
+		    
+		/*
+		** Otherwise, it is not one of the reserved addresses,
+		** so handle it like a normal DU type.
+		*/
+		du_type_layout = ra_layout->MR_ra_other_functors;
+		goto du_type;
+	    }
+
         case MR_TYPECTOR_REP_DU_USEREQ:
             expand_info->non_canonical_type = TRUE;
             /* fall through */
 
         case MR_TYPECTOR_REP_DU:
+	    du_type_layout = type_ctor_info->type_layout.layout_du;
+	    /* fall through */
+
+	du_type:
             {
                 const MR_DuPtagLayout   *ptag_layout;
                 const MR_DuFunctorDesc  *functor_desc;
@@ -215,7 +269,7 @@
 
                 data = *data_word_ptr;
                 ptag = MR_tag(data);
-                ptag_layout = &type_ctor_info->type_layout.layout_du[ptag];
+                ptag_layout = &du_type_layout[ptag];
 
                 switch (ptag_layout->MR_sectag_locn) {
                     case MR_SECTAG_NONE:
Index: runtime/mercury_tabling.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_tabling.c,v
retrieving revision 1.42
diff -u -d -r1.42 mercury_tabling.c
--- runtime/mercury_tabling.c	31 May 2001 06:00:16 -0000	1.42
+++ runtime/mercury_tabling.c	22 Oct 2001 12:14:49 -0000
@@ -618,6 +618,7 @@
 MR_table_type(MR_TrieNode table, MR_TypeInfo type_info, MR_Word data)
 {
     MR_TypeCtorInfo type_ctor_info;
+    MR_DuTypeLayout du_type_layout;
 
     type_ctor_info = MR_TYPEINFO_GET_TYPE_CTOR_INFO(type_info);
 
@@ -635,8 +636,57 @@
                     type_ctor_info->type_ctor_num_functors, data);
             break;
 
+        case MR_TYPECTOR_REP_RESERVED_ADDR: 
+        case MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ: 
+	    {
+		int i;
+		MR_ReservedAddrTypeLayout ra_layout =
+			    type_ctor_info->type_layout.layout_reserved_addr;
+
+		/*
+		** First check if this value is one of
+		** the numeric reserved addresses.
+		*/
+		if ((MR_Unsigned) data <
+		    (MR_Unsigned) ra_layout->MR_ra_num_res_numeric_addrs)
+		{
+		    MR_DEBUG_TABLE_ENUM(table,
+                        type_ctor_info->type_ctor_num_functors,
+                        ra_layout->MR_ra_constants[data]->MR_ra_functor_ordinal);
+		    break;
+		}
+
+		/*
+		** Next check if this value is one of the
+		** the symbolic reserved addresses.
+		*/
+		for (i = 0; i < ra_layout->MR_ra_num_res_symbolic_addrs; i++) {
+		    if (data == (MR_Word) ra_layout->MR_ra_res_symbolic_addrs[i]) {
+			int offset = i + ra_layout->MR_ra_num_res_numeric_addrs;
+			MR_DEBUG_TABLE_ENUM(table,
+			    type_ctor_info->type_ctor_num_functors,
+			    ra_layout->MR_ra_constants[offset]->
+			    	MR_ra_functor_ordinal);
+			/* "break" here would just exit the "for" loop */
+			return table;
+		    }
+		}
+		    
+		/*
+		** Otherwise, it is not one of the reserved addresses,
+		** so handle it like a normal DU type.
+		*/
+		du_type_layout = ra_layout->MR_ra_other_functors;
+		goto du_type;
+	    }
+
+            
         case MR_TYPECTOR_REP_DU: 
         case MR_TYPECTOR_REP_DU_USEREQ: 
+	    du_type_layout = type_ctor_info->type_layout.layout_du;
+	    /* fall through */
+	
+	du_type:
             {
                 MR_MemoryList           allocated_memory_cells = NULL;
                 const MR_DuPtagLayout   *ptag_layout;
@@ -650,7 +700,7 @@
                 int                     i;
 
                 ptag = MR_tag(data);
-                ptag_layout = &type_ctor_info->type_layout.layout_du[ptag];
+                ptag_layout = &du_type_layout[ptag];
 
                 switch (ptag_layout->MR_sectag_locn) {
                 case MR_SECTAG_NONE:
Index: runtime/mercury_unify_compare_body.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_unify_compare_body.h,v
retrieving revision 1.11
diff -u -d -r1.11 mercury_unify_compare_body.h
--- runtime/mercury_unify_compare_body.h	17 Jul 2001 07:04:18 -0000	1.11
+++ runtime/mercury_unify_compare_body.h	22 Oct 2001 12:03:09 -0000
@@ -81,6 +81,10 @@
                 layout_notag->MR_notag_functor_arg_type;
             goto start_label;
 
+        case MR_TYPECTOR_REP_RESERVED_ADDR:
+            MR_fatal_error("sorry, not implemented: "
+		    	"MR_COMPARE_BY_RTTI for RESERVED_ADDR");
+
         case MR_TYPECTOR_REP_DU:
             {
                 const MR_DuFunctorDesc  *functor_desc;
@@ -291,12 +295,14 @@
         case MR_TYPECTOR_REP_EQUIV_VAR:
         case MR_TYPECTOR_REP_NOTAG:
         case MR_TYPECTOR_REP_NOTAG_GROUND:
+        case MR_TYPECTOR_REP_RESERVED_ADDR:
         case MR_TYPECTOR_REP_DU:
             /* fall through */
 
 #endif
 
         case MR_TYPECTOR_REP_ENUM_USEREQ:
+        case MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ:
         case MR_TYPECTOR_REP_DU_USEREQ:
         case MR_TYPECTOR_REP_NOTAG_USEREQ:
         case MR_TYPECTOR_REP_NOTAG_GROUND_USEREQ:
Index: compiler/mlds_to_gcc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_gcc.m,v
retrieving revision 1.51
diff -u -d -r1.51 mlds_to_gcc.m
--- compiler/mlds_to_gcc.m	24 Aug 2001 15:44:54 -0000	1.51
+++ compiler/mlds_to_gcc.m	24 Oct 2001 04:26:44 -0000
@@ -1899,6 +1899,11 @@
 	build_sized_array_type('MR_ConstString', Size, GCC_Type).
 build_rtti_type(field_types(_), Size, GCC_Type) -->
 	build_sized_array_type('MR_PseudoTypeInfo', Size, GCC_Type).
+build_rtti_type(reserved_addrs, Size, GCC_Type) -->
+	build_sized_array_type(gcc__ptr_type_node, Size, GCC_Type).
+build_rtti_type(reserved_addr_functors, Size, GCC_Type) -->
+	{ MR_ReservedAddrFunctorDescPtr = gcc__ptr_type_node },
+	build_sized_array_type(MR_ReservedAddrFunctorDescPtr, Size, GCC_Type).
 build_rtti_type(enum_functor_desc(_), _, GCC_Type) -->
 	% typedef struct {
 	%     MR_ConstString      MR_enum_functor_name;
@@ -1948,6 +1953,17 @@
 		 MR_ConstStringPtr	- "MR_du_functor_arg_names",
 		 MR_DuExistInfoPtr	- "MR_du_functor_exist_info"],
 		GCC_Type).
+build_rtti_type(reserved_addr_functor_desc(_), _, GCC_Type) -->
+	% typedef struct {
+	%     MR_ConstString      MR_ra_functor_name;
+	%     MR_int_least32_t    MR_ra_functor_ordinal;
+	%     const void *        MR_ra_functor_reserved_addr;
+	% } MR_EnumFunctorDesc;
+	build_struct_type("MR_ReservedAddrFunctorDesc",
+		['MR_ConstString'	- "MR_ra_functor_name",
+		 'MR_int_least32_t'	- "MR_ra_functor_ordinal",
+		 gcc__ptr_type_node	- "MR_ra_functor_reserved_addr"],
+		GCC_Type).
 build_rtti_type(enum_name_ordered_table, Size, GCC_Type) -->
 	{ MR_EnumFunctorDescPtr = gcc__ptr_type_node },
 	build_sized_array_type(MR_EnumFunctorDescPtr, Size, GCC_Type).
@@ -1972,6 +1988,21 @@
 		 gcc__ptr_type_node	- "MR_sectag_alternatives"],
 		MR_DuPtagLayout),
 	build_sized_array_type(MR_DuPtagLayout, Size, GCC_Type).
+build_rtti_type(reserved_addr_table, _, GCC_Type) -->
+	% typedef struct {
+	%     MR_int_least16_t    MR_ra_num_res_numeric_addrs;
+	%     MR_int_least16_t    MR_ra_num_res_symbolic_addrs;
+	%     const void * const *MR_ra_res_symbolic_addrs;
+	%     const MR_ReservedAddrFunctorDesc * const * MR_ra_constants;
+	%     MR_DuTypeLayout     MR_ra_other_functors;  
+	% } MR_ReservedAddrTypeDesc;
+	build_struct_type("MR_ReservedAddrTypeDesc",
+		['MR_int_least16_t'	- "MR_ra_num_res_numeric_addrs",
+		 'MR_int_least16_t'	- "MR_ra_num_res_symbolic_addrs",
+		 gcc__ptr_type_node	- "MR_ra_res_symbolic_addrs",
+		 gcc__ptr_type_node	- "MR_ra_constants",
+		 gcc__ptr_type_node	- "MR_ra_other_functors"
+		], GCC_Type).
 build_rtti_type(type_ctor_info, _, GCC_Type) -->
 	% struct MR_TypeCtorInfo_Struct {
 	%     MR_Integer          arity;
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.116
diff -u -d -r1.116 opt_debug.m
--- compiler/opt_debug.m	31 May 2001 05:59:49 -0000	1.116
+++ compiler/opt_debug.m	22 Oct 2001 15:35:37 -0000
@@ -375,6 +375,10 @@
 opt_debug__dump_rtti_name(field_types(Ordinal), Str) :-
 	string__int_to_string(Ordinal, Ordinal_str),
 	string__append("field_types_", Ordinal_str, Str).
+opt_debug__dump_rtti_name(reserved_addrs, Str) :-
+	Str = "reserved_addrs".
+opt_debug__dump_rtti_name(reserved_addr_functors, Str) :-
+	Str = "reserved_addr_functors".
 opt_debug__dump_rtti_name(enum_functor_desc(Ordinal), Str) :-
 	string__int_to_string(Ordinal, Ordinal_str),
 	string__append("enum_functor_desc_", Ordinal_str, Str).
@@ -383,6 +387,9 @@
 opt_debug__dump_rtti_name(du_functor_desc(Ordinal), Str) :-
 	string__int_to_string(Ordinal, Ordinal_str),
 	string__append("du_functor_desc_", Ordinal_str, Str).
+opt_debug__dump_rtti_name(reserved_addr_functor_desc(Ordinal), Str) :-
+	string__int_to_string(Ordinal, Ordinal_str),
+	string__append("reserved_addr_functor_desc_", Ordinal_str, Str).
 opt_debug__dump_rtti_name(enum_name_ordered_table, Str) :-
 	Str = "enum_name_ordered_table".
 opt_debug__dump_rtti_name(enum_value_ordered_table, Str) :-
@@ -394,6 +401,8 @@
 	string__append("du_stag_ordered_table_", Ptag_str, Str).
 opt_debug__dump_rtti_name(du_ptag_ordered_table, Str) :-
 	Str = "du_ptag_ordered_table".
+opt_debug__dump_rtti_name(reserved_addr_table, Str) :-
+	Str = "reserved_addr_table".
 opt_debug__dump_rtti_name(type_ctor_info, Str) :-
 	Str = "type_ctor_info".
 opt_debug__dump_rtti_name(base_typeclass_info(_ModuleName, ClassId,
Index: compiler/rtti.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rtti.m,v
retrieving revision 1.13
diff -u -d -r1.13 rtti.m
--- compiler/rtti.m	31 May 2001 05:59:52 -0000	1.13
+++ compiler/rtti.m	23 Oct 2001 01:19:33 -0000
@@ -56,6 +56,7 @@
 :- type type_ctor_rep
 	--->	enum(equality_axioms)
 	;	du(equality_axioms)
+	;	reserved_addr(equality_axioms)
 	;	notag(equality_axioms, equiv_type_inst)
 	;	equiv(equiv_type_inst)
 	;	unknown.
@@ -74,6 +75,9 @@
 	;	du_layout(
 			rtti_name
 		)
+	;	reserved_addr_layout(
+			rtti_name
+		)
 	;	equiv_layout(
 			rtti_data	% a pseudo_type_info rtti_data
 		)
@@ -175,6 +179,26 @@
 						% (as pseudo_type_info
 						% rtti_data)
 		)
+	;	reserved_addrs(
+			rtti_type_id,		% identifies the type
+
+			% The remaining argument of this function symbol
+			% corresponds to an array of const void *.
+
+			list(reserved_address)	% gives the values of the
+						% reserved addresses for that
+						% type
+		)
+	;	reserved_addr_functors(
+			rtti_type_id,		% identifies the type
+
+			% The remaining argument of this function symbol
+			% corresponds to an array of MR_ReservedAddrFunctorDesc
+
+			list(rtti_name)		% gives the functor descriptors
+						% for the reserved_addr
+						% functors for that type
+		)
 	;	enum_functor_desc(
 			rtti_type_id,		% identifies the type
 
@@ -235,6 +259,17 @@
 						% type variables, if any
 						% (an exist_info rtti_name)
 		)
+	;	reserved_addr_functor_desc(
+			rtti_type_id,		% identifies the type
+
+			% The remaining arguments of this function symbol
+			% correspond one-to-one to the fields of
+			% MR_ReservedAddrFunctorDesc.
+
+			string,			% functor name
+			int,			% ordinal number of functor
+			reserved_address	% value
+		)
 	;	enum_name_ordered_table(
 			rtti_type_id,		% identifies the type
 
@@ -252,6 +287,21 @@
 
 			list(rtti_name)
 		)	
+	;	reserved_addr_table(
+			rtti_type_id,		% identifies the type
+
+			% The remaining argument of this function symbol
+			% corresponds to the functors_du alternative of
+			% the MR_ReservedAddrTypeDesc C type.
+			int,		% number of reserved numeric addresses
+			int,		% number of reserved symbolic addresses
+			rtti_name,	% the values of the reserved addresses
+			rtti_name,	% the reserved_addr_functor_descs
+					% for all the constants that are
+					% represented as reserved addresses
+			rtti_name	% the du_ptag_ordered_table for
+					% the remaining functors
+		)	
 	;	du_name_ordered_table(
 			rtti_type_id,		% identifies the type
 
@@ -316,14 +366,18 @@
 	;	exist_info(int)			% functor ordinal
 	;	field_names(int)		% functor ordinal
 	;	field_types(int)		% functor ordinal
+	;	reserved_addrs
+	;	reserved_addr_functors
 	;	enum_functor_desc(int)		% functor ordinal
 	;	notag_functor_desc
 	;	du_functor_desc(int)		% functor ordinal
+	;	reserved_addr_functor_desc(int)	% functor ordinal
 	;	enum_name_ordered_table
 	;	enum_value_ordered_table
 	;	du_name_ordered_table
 	;	du_stag_ordered_table(int)	% primary tag
 	;	du_ptag_ordered_table
+	;	reserved_addr_table
 	;	type_ctor_info
 	;	pseudo_type_info(pseudo_type_info)
 	;	base_typeclass_info(
@@ -451,12 +505,18 @@
 	RttiTypeId, field_names(Ordinal)).
 rtti_data_to_name(field_types(RttiTypeId, Ordinal, _),
 	RttiTypeId, field_types(Ordinal)).
+rtti_data_to_name(reserved_addrs(RttiTypeId, _),
+	RttiTypeId, reserved_addrs).
+rtti_data_to_name(reserved_addr_functors(RttiTypeId, _),
+	RttiTypeId, reserved_addr_functors).
 rtti_data_to_name(enum_functor_desc(RttiTypeId, _, Ordinal),
 	RttiTypeId, enum_functor_desc(Ordinal)).
 rtti_data_to_name(notag_functor_desc(RttiTypeId, _, _, _),
 	RttiTypeId, notag_functor_desc).
 rtti_data_to_name(du_functor_desc(RttiTypeId, _,_,_,_, Ordinal, _,_,_,_,_),
 	RttiTypeId, du_functor_desc(Ordinal)).
+rtti_data_to_name(reserved_addr_functor_desc(RttiTypeId, _, Ordinal, _),
+	RttiTypeId, reserved_addr_functor_desc(Ordinal)).
 rtti_data_to_name(enum_name_ordered_table(RttiTypeId, _),
 	RttiTypeId, enum_name_ordered_table).
 rtti_data_to_name(enum_value_ordered_table(RttiTypeId, _),
@@ -467,6 +527,8 @@
 	RttiTypeId, du_stag_ordered_table(Ptag)).
 rtti_data_to_name(du_ptag_ordered_table(RttiTypeId, _),
 	RttiTypeId, du_ptag_ordered_table).
+rtti_data_to_name(reserved_addr_table(RttiTypeId, _, _, _, _, _),
+	RttiTypeId, reserved_addr_table).
 rtti_data_to_name(type_ctor_info(RttiTypeId, _,_,_,_,_,_,_,_,_,_,_,_),
 	RttiTypeId, type_ctor_info).
 rtti_data_to_name(base_typeclass_info(_, _, _, _), _, _) :-
@@ -488,14 +550,18 @@
 rtti_name_has_array_type(exist_info(_))			= no.
 rtti_name_has_array_type(field_names(_))		= yes.
 rtti_name_has_array_type(field_types(_))		= yes.
+rtti_name_has_array_type(reserved_addrs)		= yes.
+rtti_name_has_array_type(reserved_addr_functors)	= yes.
 rtti_name_has_array_type(enum_functor_desc(_))		= no.
 rtti_name_has_array_type(notag_functor_desc)		= no.
 rtti_name_has_array_type(du_functor_desc(_))		= no.
+rtti_name_has_array_type(reserved_addr_functor_desc(_))	= no.
 rtti_name_has_array_type(enum_name_ordered_table)	= yes.
 rtti_name_has_array_type(enum_value_ordered_table)	= yes.
 rtti_name_has_array_type(du_name_ordered_table)		= yes.
 rtti_name_has_array_type(du_stag_ordered_table(_))	= yes.
 rtti_name_has_array_type(du_ptag_ordered_table)		= yes.
+rtti_name_has_array_type(reserved_addr_table)		= no.
 rtti_name_has_array_type(type_ctor_info)		= no.
 rtti_name_has_array_type(pseudo_type_info(_))		= no.
 rtti_name_has_array_type(base_typeclass_info(_, _, _))	= yes.
@@ -505,14 +571,18 @@
 rtti_name_is_exported(exist_info(_))            = no.
 rtti_name_is_exported(field_names(_))           = no.
 rtti_name_is_exported(field_types(_))           = no.
+rtti_name_is_exported(reserved_addrs)           = no.
+rtti_name_is_exported(reserved_addr_functors)   = no.
 rtti_name_is_exported(enum_functor_desc(_))     = no.
 rtti_name_is_exported(notag_functor_desc)       = no.
 rtti_name_is_exported(du_functor_desc(_))       = no.
+rtti_name_is_exported(reserved_addr_functor_desc(_)) = no.
 rtti_name_is_exported(enum_name_ordered_table)  = no.
 rtti_name_is_exported(enum_value_ordered_table) = no.
 rtti_name_is_exported(du_name_ordered_table)    = no.
 rtti_name_is_exported(du_stag_ordered_table(_)) = no.
 rtti_name_is_exported(du_ptag_ordered_table)    = no.
+rtti_name_is_exported(reserved_addr_table)      = no.
 rtti_name_is_exported(type_ctor_info)           = yes.
 rtti_name_is_exported(pseudo_type_info(Pseudo)) =
 	pseudo_type_info_is_exported(Pseudo).
@@ -576,6 +646,14 @@
 		string__append_list([ModuleName, "__field_types_",
 			TypeName, "_", A_str, "_", O_str], Str)
 	;
+		RttiName = reserved_addrs,
+		string__append_list([ModuleName, "__reserved_addrs_",
+			TypeName, "_", A_str], Str)
+	;
+		RttiName = reserved_addr_functors,
+		string__append_list([ModuleName, "__reserved_addr_functors_",
+			TypeName, "_", A_str], Str)
+	;
 		RttiName = enum_functor_desc(Ordinal),
 		string__int_to_string(Ordinal, O_str),
 		string__append_list([ModuleName, "__enum_functor_desc_",
@@ -590,6 +668,11 @@
 		string__append_list([ModuleName, "__du_functor_desc_",
 			TypeName, "_", A_str, "_", O_str], Str)
 	;
+		RttiName = reserved_addr_functor_desc(Ordinal),
+		string__int_to_string(Ordinal, O_str),
+		string__append_list([ModuleName, "__reserved_addr_functor_desc_",
+			TypeName, "_", A_str, "_", O_str], Str)
+	;
 		RttiName = enum_name_ordered_table,
 		string__append_list([ModuleName, "__enum_name_ordered_",
 			TypeName, "_", A_str], Str)
@@ -611,6 +694,10 @@
 		string__append_list([ModuleName, "__du_ptag_ordered_",
 			TypeName, "_", A_str], Str)
 	;
+		RttiName = reserved_addr_table,
+		string__append_list([ModuleName, "__reserved_addr_table_",
+			TypeName, "_", A_str], Str)
+	;
 		RttiName = type_ctor_info,
 		string__append_list([ModuleName, "__type_ctor_info_",
 			TypeName, "_", A_str], Str)
@@ -708,6 +795,10 @@
 	"MR_TYPECTOR_REP_DU").
 rtti__type_ctor_rep_to_string(du(user_defined),
 	"MR_TYPECTOR_REP_DU_USEREQ").
+rtti__type_ctor_rep_to_string(reserved_addr(standard),
+	"MR_TYPECTOR_REP_RESERVED_ADDR").
+rtti__type_ctor_rep_to_string(reserved_addr(user_defined),
+	"MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ").
 rtti__type_ctor_rep_to_string(enum(standard),
 	"MR_TYPECTOR_REP_ENUM").
 rtti__type_ctor_rep_to_string(enum(user_defined),
Index: compiler/rtti_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rtti_out.m,v
retrieving revision 1.21
diff -u -d -r1.21 rtti_out.m
--- compiler/rtti_out.m	18 Mar 2001 23:09:59 -0000	1.21
+++ compiler/rtti_out.m	23 Oct 2001 06:23:32 -0000
@@ -88,6 +88,7 @@
 :- implementation.
 
 :- import_module pseudo_type_info, code_util, llds, prog_out, c_util.
+:- import_module error_util.
 :- import_module options, globals.
 :- import_module int, string, list, require, std_util.
 
@@ -154,6 +155,38 @@
 		output_addr_of_rtti_datas(Types),
 		io__write_string("};\n")
 	).
+output_rtti_data_defn(reserved_addrs(RttiTypeId, ReservedAddrs),
+		DeclSet0, DeclSet) -->
+	output_generic_rtti_data_defn_start(RttiTypeId, reserved_addrs,
+		DeclSet0, DeclSet),
+	(
+			% ANSI/ISO C doesn't allow empty arrays, so
+			% place a dummy value in the array if necessary.
+		{ ReservedAddrs = [] }
+	->
+		io__write_string("= { NULL };\n")
+	;
+		io__write_string(" = {\n"),
+		io__write_list(ReservedAddrs, ",\n\t", output_reserved_address),
+		io__write_string("\n};\n")
+	).
+output_rtti_data_defn(reserved_addr_functors(RttiTypeId, FunctorDescs),
+		DeclSet0, DeclSet) -->
+	output_rtti_addrs_decls(RttiTypeId, FunctorDescs, "", "", 0, _,
+		DeclSet0, DeclSet1),
+	output_generic_rtti_data_defn_start(RttiTypeId, reserved_addr_functors,
+		DeclSet1, DeclSet),
+	(
+			% ANSI/ISO C doesn't allow empty arrays, so
+			% place a dummy value in the array if necessary.
+		{ FunctorDescs = [] }
+	->
+		io__write_string("= { NULL };\n")
+	;
+		io__write_string(" = {\n"),
+		output_addr_of_rtti_addrs(RttiTypeId, FunctorDescs),
+		io__write_string("};\n")
+	).
 output_rtti_data_defn(enum_functor_desc(RttiTypeId, FunctorName, Ordinal),
 		DeclSet0, DeclSet) -->
 	output_generic_rtti_data_defn_start(RttiTypeId,
@@ -254,6 +287,17 @@
 		io__write_string("NULL")
 	),
 	io__write_string("\n};\n").
+output_rtti_data_defn(reserved_addr_functor_desc(RttiTypeId, FunctorName, Ordinal,
+		ReservedAddr), DeclSet0, DeclSet) -->
+	output_generic_rtti_data_defn_start(RttiTypeId,
+		reserved_addr_functor_desc(Ordinal), DeclSet0, DeclSet),
+	io__write_string(" = {\n\t"""),
+	c_util__output_quoted_string(FunctorName),
+	io__write_string(""",\n\t"),
+	io__write_int(Ordinal),
+	io__write_string(",\n\t"),
+	output_reserved_address(ReservedAddr),
+	io__write_string("\n};\n").
 output_rtti_data_defn(enum_name_ordered_table(RttiTypeId, Functors),
 		DeclSet0, DeclSet) -->
 	output_rtti_addrs_decls(RttiTypeId, Functors, "", "", 0, _,
@@ -308,6 +352,26 @@
 	),
 	output_ptag_layout_defns(PtagLayouts, RttiTypeId),
 	io__write_string("\n};\n").
+output_rtti_data_defn(reserved_addr_table(RttiTypeId, NumNumericReservedAddrs,
+		NumSymbolicReservedAddrs, SymbolicReservedAddrs,
+		ReservedAddrFunctorDescs, DuFunctorLayout),
+		DeclSet0, DeclSet) -->
+	output_rtti_addrs_decls(RttiTypeId, [SymbolicReservedAddrs,
+			DuFunctorLayout, ReservedAddrFunctorDescs],
+			"", "", 0, _, DeclSet0, DeclSet1),
+	output_generic_rtti_data_defn_start(RttiTypeId,
+		reserved_addr_table, DeclSet1, DeclSet),
+	io__write_string(" = {\n\t"),
+	io__write_int(NumNumericReservedAddrs),
+	io__write_string(",\n\t"),
+	io__write_int(NumSymbolicReservedAddrs),
+	io__write_string(",\n\t"),
+	output_rtti_addr(RttiTypeId, SymbolicReservedAddrs),
+	io__write_string(",\n\t"),
+	output_rtti_addr(RttiTypeId, ReservedAddrFunctorDescs),
+	io__write_string(",\n\t"),
+	output_rtti_addr(RttiTypeId, DuFunctorLayout),
+	io__write_string("\n};\n").
 output_rtti_data_defn(type_ctor_info(RttiTypeId, Unify, Compare,
 		CtorRep, Solver, Init, Version, NumPtags, NumFunctors,
 		FunctorsInfo, LayoutInfo, _MaybeHashCons, _Prettyprinter),
@@ -385,6 +449,11 @@
 		output_rtti_addr(RttiTypeId, DuLayoutInfo),
 		io__write_string(" }")
 	;
+		{ LayoutInfo = reserved_addr_layout(RaLayoutInfo) },
+		io__write_string("{ (void *) &"),
+		output_rtti_addr(RttiTypeId, RaLayoutInfo),
+		io__write_string(" }")
+	;
 		{ LayoutInfo = equiv_layout(EquivTypeInfo) },
 		io__write_string("{ (void *) "),
 		output_addr_of_rtti_data(EquivTypeInfo),
@@ -517,6 +586,10 @@
 		DeclSet0, DeclSet) -->
 	output_generic_rtti_data_decl(RttiTypeId, DuLayoutInfo,
 		DeclSet0, DeclSet).
+output_layout_info_decl(RttiTypeId, reserved_addr_layout(RaLayoutInfo),
+		DeclSet0, DeclSet) -->
+	output_generic_rtti_data_decl(RttiTypeId, RaLayoutInfo,
+		DeclSet0, DeclSet).
 output_layout_info_decl(_RttiTypeId, equiv_layout(EquivRttiData),
 		DeclSet0, DeclSet) -->
 	output_rtti_data_decl(EquivRttiData, DeclSet0, DeclSet).
@@ -568,6 +641,20 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pred output_reserved_address(reserved_address::in,
+	io__state::di, io__state::uo) is det.
+
+output_reserved_address(null_pointer) -->
+	io__write_string("NULL").
+output_reserved_address(small_pointer(Val)) -->
+	io__write_string("(const void *) "),
+	io__write_int(Val).
+output_reserved_address(reserved_object(_, _, _)) -->
+	% These should only be used for the MLDS back-end
+	{ unexpected(this_file, "reserved_object") }.
+
+%-----------------------------------------------------------------------------%
+
 output_rtti_data_decl(RttiData, DeclSet0, DeclSet) -->
 	( { RttiData = pseudo_type_info(type_var(_)) } ->
 		% These just get represented as integers,
@@ -1038,14 +1125,18 @@
 rtti_name_would_include_code_addr(exist_info(_)) =                no.
 rtti_name_would_include_code_addr(field_names(_)) =               no.
 rtti_name_would_include_code_addr(field_types(_)) =               no.
+rtti_name_would_include_code_addr(reserved_addrs) =               no.
+rtti_name_would_include_code_addr(reserved_addr_functors) =       no.
 rtti_name_would_include_code_addr(enum_functor_desc(_)) =         no.
 rtti_name_would_include_code_addr(notag_functor_desc) =           no.
 rtti_name_would_include_code_addr(du_functor_desc(_)) =           no.
+rtti_name_would_include_code_addr(reserved_addr_functor_desc(_)) = no.
 rtti_name_would_include_code_addr(enum_name_ordered_table) =      no.
 rtti_name_would_include_code_addr(enum_value_ordered_table) =     no.
 rtti_name_would_include_code_addr(du_name_ordered_table) =        no.
 rtti_name_would_include_code_addr(du_stag_ordered_table(_)) =     no.
 rtti_name_would_include_code_addr(du_ptag_ordered_table) =        no.
+rtti_name_would_include_code_addr(reserved_addr_table) =          no.
 rtti_name_would_include_code_addr(type_ctor_info) =               yes.
 rtti_name_would_include_code_addr(base_typeclass_info(_, _, _)) = yes.
 rtti_name_would_include_code_addr(pseudo_type_info(Pseudo)) =
@@ -1079,14 +1170,18 @@
 rtti_name_c_type(exist_info(_),            "MR_DuExistInfo", "").
 rtti_name_c_type(field_names(_),           "MR_ConstString", "[]").
 rtti_name_c_type(field_types(_),           "MR_PseudoTypeInfo", "[]").
+rtti_name_c_type(reserved_addrs,           "/* const */ void *", "[]").
+rtti_name_c_type(reserved_addr_functors,   "MR_ReservedAddrFunctorDesc *", "[]").
 rtti_name_c_type(enum_functor_desc(_),     "MR_EnumFunctorDesc", "").
 rtti_name_c_type(notag_functor_desc,       "MR_NotagFunctorDesc", "").
 rtti_name_c_type(du_functor_desc(_),       "MR_DuFunctorDesc", "").
+rtti_name_c_type(reserved_addr_functor_desc(_), "MR_ReservedAddrFunctorDesc", "").
 rtti_name_c_type(enum_name_ordered_table,  "MR_EnumFunctorDesc *", "[]").
 rtti_name_c_type(enum_value_ordered_table, "MR_EnumFunctorDesc *", "[]").
 rtti_name_c_type(du_name_ordered_table,    "MR_DuFunctorDesc *", "[]").
 rtti_name_c_type(du_stag_ordered_table(_), "MR_DuFunctorDesc *", "[]").
 rtti_name_c_type(du_ptag_ordered_table,    "MR_DuPtagLayout", "[]").
+rtti_name_c_type(reserved_addr_table,      "MR_ReservedAddrTypeLayout", "").
 rtti_name_c_type(type_ctor_info,           "struct MR_TypeCtorInfo_Struct",
 						"").
 rtti_name_c_type(base_typeclass_info(_, _, _), "MR_Code *", "[]").
@@ -1111,5 +1206,12 @@
 		TypeInfoStruct, "") :-
 	TypeInfoStruct = string__format("struct MR_HO_PseudoTypeInfo_Struct%d",
 		[i(list__length(ArgTypes))]).
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+this_file = "rtti_out.m".
+
+:- end_module rtti_out.
 
 %-----------------------------------------------------------------------------%
Index: compiler/rtti_to_mlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rtti_to_mlds.m,v
retrieving revision 1.18
diff -u -d -r1.18 rtti_to_mlds.m
--- compiler/rtti_to_mlds.m	9 Jul 2001 15:55:07 -0000	1.18
+++ compiler/rtti_to_mlds.m	22 Oct 2001 16:13:19 -0000
@@ -30,7 +30,7 @@
 :- func mlds_rtti_type_name(rtti_name) = string.
 
 :- implementation.
-:- import_module prog_data.
+:- import_module prog_data, hlds_data.
 :- import_module pseudo_type_info, prog_util, prog_out, type_util.
 :- import_module ml_code_util, ml_unify_gen.
 :- import_module bool, list, std_util, string, term, require.
@@ -142,6 +142,15 @@
 	Init = gen_init_array(
 		gen_init_cast_rtti_data(mlds__pseudo_type_info_type,
 		ModuleName), Types).
+gen_init_rtti_data_defn(reserved_addrs(_RttiTypeId, ReservedAddrs),
+		_ModuleName, _, Init, []) :-
+	Init = gen_init_array(gen_init_reserved_address, ReservedAddrs).
+gen_init_rtti_data_defn(reserved_addr_functors(RttiTypeId,
+			ReservedAddrFunctorDescs),
+		ModuleName, _, Init, []) :-
+	Init = gen_init_array(
+		gen_init_rtti_name(ModuleName, RttiTypeId),
+		ReservedAddrFunctorDescs).
 gen_init_rtti_data_defn(enum_functor_desc(_RttiTypeId, FunctorName, Ordinal),
 		_, _, Init, []) :-
 	Init = init_struct([
@@ -177,6 +186,13 @@
 			gen_init_rtti_name(ModuleName, RttiTypeId),
 			MaybeExist)
 	]).
+gen_init_rtti_data_defn(reserved_addr_functor_desc(_RttiTypeId, FunctorName, Ordinal,
+		ReservedAddress), _, _, Init, []) :-
+	Init = init_struct([
+		gen_init_string(FunctorName),
+		gen_init_int(Ordinal),
+		gen_init_reserved_address(ReservedAddress)
+	]).
 gen_init_rtti_data_defn(enum_name_ordered_table(RttiTypeId, Functors),
 		ModuleName, _, Init, []) :-
 	Init = gen_init_rtti_names_array(ModuleName, RttiTypeId, Functors).
@@ -193,6 +209,16 @@
 		ModuleName, _, Init, []) :-
 	Init = gen_init_array(gen_init_ptag_layout_defn(ModuleName, RttiTypeId),
 		PtagLayouts).
+gen_init_rtti_data_defn(reserved_addr_table(RttiTypeId,
+		NumNumeric, NumSymbolic, ReservedAddrs, FunctorDescs, DuLayout),
+		ModuleName, _, Init, []) :-
+	Init = init_struct([
+		gen_init_int(NumNumeric),
+		gen_init_int(NumSymbolic),
+		gen_init_rtti_name(ModuleName, RttiTypeId, ReservedAddrs),
+		gen_init_rtti_name(ModuleName, RttiTypeId, FunctorDescs),
+		gen_init_rtti_name(ModuleName, RttiTypeId, DuLayout)
+	]).
 gen_init_rtti_data_defn(type_ctor_info(RttiTypeId, UnifyProc, CompareProc,
 		CtorRep, SolverProc, InitProc, Version, NumPtags, NumFunctors,
 		FunctorsInfo, LayoutInfo, _MaybeHashCons,
@@ -277,6 +303,9 @@
 gen_init_layout_info(du_layout(DuLayoutInfo), ModuleName, RttiTypeId) =
 	gen_init_cast_rtti_name(mlds__generic_type, ModuleName, RttiTypeId,
 		DuLayoutInfo).
+gen_init_layout_info(reserved_addr_layout(RaLayoutInfo), ModuleName, RttiTypeId) =
+	gen_init_cast_rtti_name(mlds__generic_type, ModuleName, RttiTypeId,
+		RaLayoutInfo).
 gen_init_layout_info(equiv_layout(EquivTypeInfo), ModuleName, _RttiTypeId) =
 	gen_init_cast_rtti_data(mlds__generic_type, ModuleName,
 		EquivTypeInfo).
@@ -604,20 +633,32 @@
 gen_init_boxed_int(Int) =
 	init_obj(unop(box(mlds__native_int_type), const(int_const(Int)))).
 
+:- func gen_init_reserved_address(reserved_address) = mlds__initializer.
+	/* XXX using `mlds__generic_type' here is probably wrong */
+gen_init_reserved_address(ReservedAddress) =
+	init_obj(ml_gen_reserved_address(ReservedAddress, mlds__generic_type)).
+
 %-----------------------------------------------------------------------------%
 
+% the type names mentioned here should be defined in runtime/mercury.h
+% (or in some header file that is included by that one)
+
 mlds_rtti_type_name(exist_locns(_)) =		"DuExistLocn".
 mlds_rtti_type_name(exist_info(_)) =		"DuExistInfo".
 mlds_rtti_type_name(field_names(_)) =		"ConstString".
 mlds_rtti_type_name(field_types(_)) =		"PseudoTypeInfo".
+mlds_rtti_type_name(reserved_addrs) =		"ReservedAddrs".
+mlds_rtti_type_name(reserved_addr_functors) =	"ReservedAddrFunctors".
 mlds_rtti_type_name(enum_functor_desc(_)) =	"EnumFunctorDesc".
 mlds_rtti_type_name(notag_functor_desc) =	"NotagFunctorDesc".
 mlds_rtti_type_name(du_functor_desc(_)) =	"DuFunctorDesc".
+mlds_rtti_type_name(reserved_addr_functor_desc(_)) = "ReservedAddrFunctorDesc".
 mlds_rtti_type_name(enum_name_ordered_table) =	"EnumFunctorDescPtr".
 mlds_rtti_type_name(enum_value_ordered_table) =	"EnumFunctorDescPtr".
 mlds_rtti_type_name(du_name_ordered_table) =	"DuFunctorDescPtr".
 mlds_rtti_type_name(du_stag_ordered_table(_)) =	"DuFunctorDescPtr".
 mlds_rtti_type_name(du_ptag_ordered_table) =	"DuPtagLayout".
+mlds_rtti_type_name(reserved_addr_table) =	"ReservedAddrTypeDesc".
 mlds_rtti_type_name(type_ctor_info) =		"TypeCtorInfo_Struct".
 mlds_rtti_type_name(base_typeclass_info(_, _, _)) = "BaseTypeclassInfo".
 mlds_rtti_type_name(pseudo_type_info(Pseudo)) =
Index: compiler/type_ctor_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/type_ctor_info.m,v
retrieving revision 1.13
diff -u -d -r1.13 type_ctor_info.m
--- compiler/type_ctor_info.m	18 Mar 2001 23:09:59 -0000	1.13
+++ compiler/type_ctor_info.m	24 Oct 2001 03:51:32 -0000
@@ -251,7 +251,7 @@
 	hlds_data__get_type_defn_body(HldsDefn, TypeBody),
 	(
 		TypeBody = uu_type(_Alts),
-		error("type_ctor_layout: sorry, undiscriminated union unimplemented\n")
+		sorry(this_file, "undiscriminated union")
 	;
 		TypeBody = abstract_type,
 		TypeCtorRep = unknown,
@@ -366,7 +366,7 @@
 %---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
 
-% Make the functor and notag tables for a notag type.
+% Make the functor and layout tables for a notag type.
 
 :- pred type_ctor_info__make_notag_tables(sym_name::in, (type)::in,
 	maybe(string)::in, rtti_type_id::in, list(rtti_data)::out,
@@ -394,7 +394,7 @@
 
 :- type name_sort_info == assoc_list(pair(string, int), rtti_name).
 
-% Make the functor and notag tables for an enum type.
+% Make the functor and layout tables for an enum type.
 
 :- pred type_ctor_info__make_enum_tables(list(constructor)::in,
 	cons_tag_values::in, rtti_type_id::in, bool::in, list(rtti_data)::out,
@@ -476,7 +476,10 @@
 :- type tag_map == map(int, pair(sectag_locn, map(int, rtti_name))).
 :- type tag_list == assoc_list(int, pair(sectag_locn, map(int, rtti_name))).
 
-% Make the functor and notag tables for a du type.
+:- type reserved_addr_map == map(reserved_address, rtti_data).
+
+% Make the functor and layout tables for a du type
+% (including reserved_addr types).
 
 :- pred type_ctor_info__make_du_tables(list(constructor)::in,
 	cons_tag_values::in, int::in, rtti_type_id::in, module_info::in,
@@ -494,9 +497,11 @@
 		InitTag = 0
 	),
 	map__init(TagMap0),
+	map__init(ReservedAddrMap0),
 	type_ctor_info__make_du_functor_tables(Ctors, InitTag, ConsTagMap,
 		RttiTypeId, ModuleInfo,
-		FunctorDescs, SortInfo0, TagMap0, TagMap),
+		FunctorDescs, SortInfo0, TagMap0, TagMap,
+		ReservedAddrMap0, ReservedAddrMap),
 	list__sort(SortInfo0, SortInfo),
 	assoc_list__values(SortInfo, NameOrderedRttiNames),
 
@@ -508,11 +513,69 @@
 	type_ctor_info__make_du_ptag_ordered_table(TagMap, InitTag, MaxPtag,
 		RttiTypeId, ValueOrderedTableRttiName, ValueOrderedTables,
 		NumPtags),
-	LayoutInfo = du_layout(ValueOrderedTableRttiName),
+	DuLayoutInfo = du_layout(ValueOrderedTableRttiName),
 	list__append([NameOrderedTable | FunctorDescs], ValueOrderedTables,
-		TypeTables).
+		TypeTables0),
+	( map__is_empty(ReservedAddrMap) ->
+		TypeTables = TypeTables0,
+		LayoutInfo = DuLayoutInfo
+	;
+		type_ctor_info__make_reserved_addr_layout(RttiTypeId,
+			ReservedAddrMap, ValueOrderedTableRttiName,
+			RALayoutRttiName, RALayoutTables),
+				% XXX does it matter what order they go in?
+		TypeTables = RALayoutTables ++ TypeTables0,
+		LayoutInfo = reserved_addr_layout(RALayoutRttiName)
+	).
 
-% Create an enum_functor_desc structure for each functor in a du type.
+:- pred type_ctor_info__make_reserved_addr_layout(rtti_type_id::in,
+		reserved_addr_map::in, rtti_name::in,
+		rtti_name::out, list(rtti_data)::out) is det.
+
+type_ctor_info__make_reserved_addr_layout(RttiTypeId, ReservedAddrMap,
+		DuTableRttiName, RALayoutRttiName, RALayoutTables) :-
+	%
+	% split the reserved addresses into numeric addresses (including null)
+	% and symbolic addresses.
+	%
+	ReservedAddrAssocList = map__to_sorted_assoc_list(ReservedAddrMap),
+	list__filter((pred(RA - _::in) is semidet :-
+			RA = reserved_object(_, _, _)),
+		ReservedAddrAssocList,
+		SymbolicAddrAssocList, NumericAddrAssocList),
+
+	%
+	% fill in the tables pointed to by the reserved_addr_table
+	%
+	SymbolicAddrList = assoc_list__keys(SymbolicAddrAssocList),
+	SymbolicAddrTable = reserved_addrs(RttiTypeId, SymbolicAddrList),
+	ReservedAddrFunctorDescTables =
+			assoc_list__values(ReservedAddrAssocList),
+	ReservedAddrFunctorDescs = list__map(
+		(func(RAFD) = Name :-
+			rtti_data_to_name(RAFD, _RttiTypeId, Name)),
+		ReservedAddrFunctorDescTables),
+	ReservedAddrFunctorTable = reserved_addr_functors(
+			RttiTypeId, ReservedAddrFunctorDescs),
+	%
+	% fill in the reserved_addr_table,
+	% which describes the representation of this type
+	%
+	NumNumericReservedAddrs = list__length(NumericAddrAssocList),
+	NumSymbolicReservedAddrs = list__length(SymbolicAddrAssocList),
+	RALayoutTable = reserved_addr_table(RttiTypeId,
+		NumNumericReservedAddrs,
+		NumSymbolicReservedAddrs,
+		reserved_addrs,
+		reserved_addr_functors,
+		DuTableRttiName),
+	RALayoutRttiName = reserved_addr_table,
+	
+	% put it all together
+	RALayoutTables = ReservedAddrFunctorDescTables ++
+		[ReservedAddrFunctorTable, SymbolicAddrTable, RALayoutTable].
+
+% Create a du_functor_desc structure for each functor in a du type.
 % Besides returning a list of the rtti names of their du_functor_desc
 % structures, we return two other items of information. The SortInfo
 % enables our caller to sort these rtti names on functor name and then arity,
@@ -520,44 +583,48 @@
 % groups the rttis into groups depending on their primary tags; this is
 % how the type layout structure is constructed.
 
+:- type cons_representation
+	--->	reserved_address(reserved_address)
+	;	tagged_data(
+			tag_bits,	% primary tag value
+			sectag_locn,	% secondary tag location
+			int		% secondary tag value
+		).
+
 :- pred type_ctor_info__make_du_functor_tables(list(constructor)::in,
 	int::in, cons_tag_values::in, rtti_type_id::in, module_info::in,
 	list(rtti_data)::out, name_sort_info::out,
-	tag_map::in, tag_map::out) is det.
+	tag_map::in, tag_map::out,
+	reserved_addr_map::in, reserved_addr_map::out) is det.
 
 type_ctor_info__make_du_functor_tables([], _, _, _, _,
-		[], [], TagMap, TagMap).
+		[], [], TagMap, TagMap, RAMap, RAMap).
 type_ctor_info__make_du_functor_tables([Functor | Functors], Ordinal,
 		ConsTagMap, RttiTypeId, ModuleInfo,
-		Tables, SortInfo, TagMap0, TagMap) :-
+		Tables, SortInfo, TagMap0, TagMap, RAMap0, RAMap) :-
 	Functor = ctor(ExistTvars, Constraints, SymName, FunctorArgs),
 	list__length(FunctorArgs, Arity),
 	unqualify_name(SymName, FunctorName),
 	RttiName = du_functor_desc(Ordinal),
 	make_cons_id_from_qualified_sym_name(SymName, FunctorArgs, ConsId),
 	map__lookup(ConsTagMap, ConsId, ConsTag),
-	( ConsTag = unshared_tag(ConsPtag) ->
-		Locn = sectag_none,
-		Ptag = ConsPtag,
-		Stag = 0,
-		type_ctor_info__update_tag_info(Ptag, Stag, Locn, RttiName,
-			TagMap0, TagMap1)
-	; ConsTag = shared_local_tag(ConsPtag, ConsStag) ->
-		Locn = sectag_local,
-		Ptag = ConsPtag,
-		Stag = ConsStag,
-		type_ctor_info__update_tag_info(Ptag, Stag, Locn, RttiName,
-			TagMap0, TagMap1)
-	; ConsTag = shared_remote_tag(ConsPtag, ConsStag) ->
-		Locn = sectag_remote,
-		Ptag = ConsPtag,
-		Stag = ConsStag,
-		type_ctor_info__update_tag_info(Ptag, Stag, Locn, RttiName,
-			TagMap0, TagMap1)
+	type_ctor_info__process_cons_tag(ConsTag, RttiName, ConsRep,
+		TagMap0, TagMap1),
+	(	
+		ConsRep = tagged_data(Ptag, Locn, Stag),
+		RAMap1 = RAMap0
 	;
-		error("unexpected cons_tag for du function symbol")
+		ConsRep = reserved_address(RA),
+		RAFunctorDesc = reserved_addr_functor_desc(RttiTypeId,
+			FunctorName, Ordinal, RA),
+		RAMap1 = map__det_insert(RAMap0, RA, RAFunctorDesc),
+		% These three fields are not really used for
+		% reserved_address const tags, but we need to fill
+		% them in with something...
+		Ptag = 0,
+		Stag = 0,
+		Locn = sectag_none
 	),
-
 	type_ctor_info__generate_arg_info_tables(ModuleInfo,
 		RttiTypeId, Ordinal, FunctorArgs, ExistTvars,
 		MaybeArgNames,
@@ -579,10 +646,48 @@
 	FunctorSortInfo = (FunctorName - Arity) - RttiName,
 	type_ctor_info__make_du_functor_tables(Functors, Ordinal + 1,
 		ConsTagMap, RttiTypeId, ModuleInfo,
-		Tables1, SortInfo1, TagMap1, TagMap),
+		Tables1, SortInfo1, TagMap1, TagMap, RAMap1, RAMap),
 	list__append([FunctorDesc | SubTables], Tables1, Tables),
 	SortInfo = [FunctorSortInfo | SortInfo1].
 
+:- pred type_ctor_info__process_cons_tag(cons_tag::in, rtti_name::in,
+		cons_representation::out, tag_map::in, tag_map::out) is det.
+
+type_ctor_info__process_cons_tag(ConsTag, RttiName, ConsRep,
+		TagMap0, TagMap) :-
+	( ConsTag = unshared_tag(ConsPtag) ->
+		Locn = sectag_none,
+		Ptag = ConsPtag,
+		Stag = 0,
+		type_ctor_info__update_tag_info(Ptag, Stag, Locn, RttiName,
+			TagMap0, TagMap),
+		ConsRep = tagged_data(Ptag, Locn, Stag)
+	; ConsTag = shared_local_tag(ConsPtag, ConsStag) ->
+		Locn = sectag_local,
+		Ptag = ConsPtag,
+		Stag = ConsStag,
+		type_ctor_info__update_tag_info(Ptag, Stag, Locn, RttiName,
+			TagMap0, TagMap),
+		ConsRep = tagged_data(Ptag, Locn, Stag)
+	; ConsTag = shared_remote_tag(ConsPtag, ConsStag) ->
+		Locn = sectag_remote,
+		Ptag = ConsPtag,
+		Stag = ConsStag,
+		type_ctor_info__update_tag_info(Ptag, Stag, Locn, RttiName,
+			TagMap0, TagMap),
+		ConsRep = tagged_data(Ptag, Locn, Stag)
+	; ConsTag = reserved_address(RA) ->
+		ConsRep = reserved_address(RA),
+		TagMap = TagMap0
+	; ConsTag = shared_with_reserved_addresses(_RAs, ThisTag) ->
+		% here we can just ignore the fact that this cons_tag is
+		% shared with reserved addresses
+		type_ctor_info__process_cons_tag(ThisTag, RttiName,
+			ConsRep, TagMap0, TagMap)
+	;
+		unexpected(this_file, "cons_tag for du function symbol")
+	).
+
 % Generate the tables that describe the arguments of a functor. 
 
 :- pred type_ctor_info__generate_arg_info_tables(module_info::in,
@@ -852,6 +957,11 @@
 type_ctor_info__get_next_cell_number(CellNumber0, Next, CellNumber) :-
 	CellNumber = CellNumber0 + 1,
 	Next = CellNumber.
+
+%---------------------------------------------------------------------------%
+
+:- func this_file = string.
+this_file = "type_ctor_info.m".
 
 %---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
Index: library/private_builtin.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/private_builtin.m,v
retrieving revision 1.81
diff -u -d -r1.81 private_builtin.m
--- library/private_builtin.m	14 Sep 2001 10:42:47 -0000	1.81
+++ library/private_builtin.m	22 Oct 2001 13:19:41 -0000
@@ -597,7 +597,9 @@
 static int MR_TYPECTOR_REP_NOTAG_GROUND_USEREQ	=28;
 static int MR_TYPECTOR_REP_EQUIV_GROUND		=29;
 static int MR_TYPECTOR_REP_TUPLE		=30;
-static int MR_TYPECTOR_REP_UNKNOWN		=31;
+static int MR_TYPECTOR_REP_RESERVED_ADDR	=31;
+static int MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ	=32;
+static int MR_TYPECTOR_REP_UNKNOWN		=33;
 
 static int MR_SECTAG_NONE				= 0;
 static int MR_SECTAG_LOCAL				= 1;
Index: library/rtti_implementation.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/rtti_implementation.m,v
retrieving revision 1.6
diff -u -d -r1.6 rtti_implementation.m
--- library/rtti_implementation.m	26 Sep 2001 12:30:08 -0000	1.6
+++ library/rtti_implementation.m	22 Oct 2001 10:11:43 -0000
@@ -108,6 +108,8 @@
 	;	notag_ground_usereq
 	;	equiv_ground
 	;	tuple
+	;	reserved_addr
+	;	reserved_addr_usereq
 	;	unknown.
 
 
@@ -533,7 +535,7 @@
 %-----------------------------------------------------------------------------%
 
 
-	% Code to perform deconstructions (not yet complete).
+	% Code to perform deconstructions (XXX not yet complete).
 	%
 	% There are many cases to implement here, only the ones that were
 	% immediately useful (e.g. called by io__write) have been implemented
@@ -731,6 +733,16 @@
 	;
 		TypeCtorRep = ticket,
 		Functor = "some_ticket", 
+		Arity = 0,
+		Arguments = []
+	;
+		TypeCtorRep = reserved_addr,
+		Functor = "some_reserved_addr", 
+		Arity = 0,
+		Arguments = []
+	;
+		TypeCtorRep = reserved_addr_usereq,
+		Functor = "some_reserved_addr_usereq", 
 		Arity = 0,
 		Arguments = []
 	;
Index: library/std_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/std_util.m,v
retrieving revision 1.246
diff -u -d -r1.246 std_util.m
--- library/std_util.m	18 Oct 2001 10:26:59 -0000	1.246
+++ library/std_util.m	23 Oct 2001 07:23:44 -0000
@@ -1621,7 +1621,7 @@
     MR_ConstString          functor_name;
     MR_Integer              arity;
     const MR_PseudoTypeInfo *arg_pseudo_type_infos;
-    MR_ConstString          *arg_names;
+    const MR_ConstString    *arg_names;
     MR_TypeCtorRep          type_ctor_rep;
     union {
         const MR_EnumFunctorDesc  *enum_functor_desc;
@@ -1640,7 +1640,7 @@
 extern	MR_Word		    ML_type_params_vector_to_list(int arity,
                             MR_TypeInfoParams type_params);
 extern	MR_Word		    ML_arg_name_vector_to_list(int arity,
-                            MR_ConstString *arg_names);
+                            const MR_ConstString *arg_names);
 extern	MR_Word		    ML_pseudo_type_info_vector_to_type_info_list(int arity,
                             MR_TypeInfoParams type_params,
                             const MR_PseudoTypeInfo *arg_pseudo_type_infos);
@@ -2218,6 +2218,8 @@
 
         case MR_TYPECTOR_REP_DU:
         case MR_TYPECTOR_REP_DU_USEREQ:
+        case MR_TYPECTOR_REP_RESERVED_ADDR:
+        case MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ:
             Ordinal = construct_info.functor_info.
                 du_functor_desc->MR_du_functor_ordinal;
             break;
@@ -2240,6 +2242,7 @@
     MR_Word             new_data;
     ML_Construct_Info   construct_info;
     bool                success;
+    MR_DuTypeLayout	du_type_layout;
 
     type_info = (MR_TypeInfo) TypeDesc;
 
@@ -2289,6 +2292,41 @@
                 MR_UNIV_OFFSET_FOR_DATA);
             break;
 
+        case MR_TYPECTOR_REP_RESERVED_ADDR:
+        case MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ:
+	    /*
+	    ** First check whether the functor we want is one of the
+	    ** reserved addresses.
+	    */
+	    {
+		int i;
+		MR_ReservedAddrTypeLayout ra_layout;
+		int total_reserved_addrs;
+		const MR_ReservedAddrFunctorDesc *functor_desc;
+
+		ra_layout = type_ctor_info->type_layout.layout_reserved_addr;
+		total_reserved_addrs = ra_layout->MR_ra_num_res_numeric_addrs
+			+ ra_layout->MR_ra_num_res_symbolic_addrs;
+
+		for (i = 0; i < total_reserved_addrs; i++) {
+		    functor_desc = ra_layout->MR_ra_constants[i];
+		    if (functor_desc->MR_ra_functor_ordinal == FunctorNumber)
+		    {
+		    	new_data = functor_desc->MR_ra_functor_reserved_addr;
+
+		        /* `break' here would just exit the `for' loop */
+			goto end_of_main_switch;
+		    }
+		}
+	    }
+		    
+	    /*
+	    ** Otherwise, it is not one of the reserved addresses,
+	    ** so handle it like a normal DU type.
+	    */
+
+	    /* fall through */
+
         case MR_TYPECTOR_REP_DU:
         case MR_TYPECTOR_REP_DU_USEREQ:
             {
@@ -2390,6 +2428,8 @@
             MR_fatal_error(""bad type_ctor_rep in std_util:construct"");
         }
 
+    end_of_main_switch:
+
         /*
         ** Create a univ.
         */
@@ -2541,6 +2581,8 @@
 
     switch(type_ctor_info->type_ctor_rep) {
 
+    case MR_TYPECTOR_REP_RESERVED_ADDR:
+    case MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ:
     case MR_TYPECTOR_REP_DU:
     case MR_TYPECTOR_REP_DU_USEREQ:
         {
@@ -2869,7 +2911,7 @@
     */
 
 MR_Word
-ML_arg_name_vector_to_list(int arity, MR_ConstString *arg_names)
+ML_arg_name_vector_to_list(int arity, const MR_ConstString *arg_names)
 {
     MR_TypeInfo arg_type;
     MR_Word     arg_names_list;
@@ -2951,9 +2993,8 @@
     switch(type_ctor_info->type_ctor_rep) {
         case MR_TYPECTOR_REP_DU:
         case MR_TYPECTOR_REP_DU_USEREQ:
-            functors = type_ctor_info->type_ctor_num_functors;
-            break;
-
+        case MR_TYPECTOR_REP_RESERVED_ADDR:
+        case MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ:
         case MR_TYPECTOR_REP_ENUM:
         case MR_TYPECTOR_REP_ENUM_USEREQ:
             functors = type_ctor_info->type_ctor_num_functors;
@@ -3267,6 +3308,7 @@
     const char *arg_name, int *arg_num_ptr)
 {
     MR_TypeCtorInfo             type_ctor_info;
+    MR_DuTypeLayout       	du_type_layout;
     const MR_DuPtagLayout       *ptag_layout;
     const MR_DuFunctorDesc      *functor_desc;
     const MR_NotagFunctorDesc   *notag_functor_desc;
@@ -3279,11 +3321,58 @@
     type_ctor_info = MR_TYPEINFO_GET_TYPE_CTOR_INFO(type_info);
 
     switch (type_ctor_info->type_ctor_rep) {
+        case MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ:
+        case MR_TYPECTOR_REP_RESERVED_ADDR:
+	    {
+		MR_ReservedAddrTypeLayout ra_layout;
+		
+	    	ra_layout = type_ctor_info->type_layout.layout_reserved_addr;
+		data = *term_ptr;
+		
+		/*
+		** First check if this value is one of
+		** the numeric reserved addresses.
+		*/
+		if ((MR_Unsigned) data <
+		    (MR_Unsigned) ra_layout->MR_ra_num_res_numeric_addrs)
+		{
+		    /*
+		    ** If so, it must be a constant, and constants never have
+		    ** any arguments.
+		    */
+		    return FALSE;
+		}
+
+		/*
+		** Next check if this value is one of the
+		** the symbolic reserved addresses.
+		*/
+		for (i = 0; i < ra_layout->MR_ra_num_res_symbolic_addrs; i++) {
+		    if (data ==
+		    	(MR_Word) ra_layout->MR_ra_res_symbolic_addrs[i])
+		    {
+			return FALSE;
+		    }
+		}
+		    
+		/*
+		** Otherwise, it is not one of the reserved addresses,
+		** so handle it like a normal DU type.
+		*/
+		du_type_layout = ra_layout->MR_ra_other_functors;
+		goto du_type;
+	    }
+
+
         case MR_TYPECTOR_REP_DU_USEREQ:
         case MR_TYPECTOR_REP_DU:
             data = *term_ptr;
+	    du_type_layout = type_ctor_info->type_layout.layout_du;
+	    /* fall through */
+
+	du_type:
             ptag = MR_tag(data);
-            ptag_layout = &type_ctor_info->type_layout.layout_du[ptag];
+            ptag_layout = &du_type_layout[ptag];
 
             switch (ptag_layout->MR_sectag_locn) {
                 case MR_SECTAG_NONE:
@@ -3562,6 +3651,9 @@
         FunctorInfo = functor_string(String)
     ; get_enum_functor_info(Univ, Enum) ->
         FunctorInfo = functor_enum(Enum)
+    %
+    % XXX we should handle reserved_addr types here
+    %
     ; get_du_functor_info(Univ, Where, Ptag, Sectag, Args) ->
         ( Where = 0 ->
             FunctorInfo = functor_unshared(Ptag, Args)
-- 
Fergus Henderson <fjh at cs.mu.oz.au>  | "... it seems to me that 15 years of
The University of Melbourne         | email is plenty for one lifetime."
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- Prof. Donald E. Knuth
--------------------------------------------------------------------------
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