[m-dev.] For Review: Bytecode interpreter (relative diff)

Levi Cameron l.cameron2 at ugrad.unimelb.edu.au
Tue Jan 30 17:44:56 AEDT 2001


Here is the relative diff (part 1)

  The main changes are cosmetic [void * vs void* means a lot
of lines show up in the diff, as does (int)1 vs (int) 1]
and the fact that code addresses are better type definitions
(mainly MB_Bytecode_Addr and MB_Native_Addr rather than simply
MB_Word *)

Levi
l.cameron2 at ugrad.unimelb.edu.au

--- ../bytecode.posted/mb_basetypes.h	Tue Jan 30 17:27:20 2001
+++ mb_basetypes.h	Mon Jan 29 18:16:34 2001
@@ -1,3 +1,4 @@
+
 /*
 ** Copyright (C) 2000-2001 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
@@ -11,11 +12,11 @@
 
 #include <stdio.h>
 
-#include <mercury_conf.h>
-#include <mercury_types.h>
-#include <mercury_float.h>
+#include "mercury_conf.h"
+#include "mercury_tags.h"
+#include "mercury_types.h"
+#include "mercury_float.h"
 
-/* XXX expects sizeof(unsigned char) == 1 */
 typedef unsigned char
 	MB_Byte;
 
@@ -28,8 +29,7 @@
 typedef MR_Unsigned
 	MB_Unsigned;
 
-/* XXX Assume char is 8 bits (Is there a system where is isn't) */
-#define MB_WORD_BITS	((sizeof(MB_Word)/sizeof(char))*8)
+#define MB_WORD_BITS	MR_WORDBITS
 
 typedef MR_Integer
 	MB_Integer;
@@ -40,8 +40,29 @@
 typedef MR_Float64
 	MB_Float64;
 
-typedef MR_Bool
+typedef MB_Byte
 	MB_Bool;
+
+/*
+** These shouldn't really be in here (they're not really basic types)
+** but putting them here stops circular header dependencies that otherwise
+** cause problems.
+*/
+	
+/*
+** Native code instruction pointer
+** Native_Addr_Struct doesn't actually exist; it is only
+** used to force type checking
+*/
+struct MB_Native_Addr_Struct;
+typedef struct MB_Native_Addr_Struct*
+	MB_Native_Addr;
+
+/* Bytecode instruction pointer */
+struct MB_BCId_Struct;
+typedef struct MB_BCId_Struct MB_BCId;
+typedef MB_BCId*
+	MB_Bytecode_Addr;
 
 #endif	/* MB_BASETYPES_H */
 
--- ../bytecode.posted/mb_bytecode.h	Tue Jan 30 14:04:54 2001
+++ mb_bytecode.h	Tue Jan 30 12:32:34 2001
@@ -1,6 +1,6 @@
 
 /*
-** Copyright (C) 1997-2001 The University of Melbourne.
+** Copyright (C) 1997,2000-2001 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
 ** Public License - see the file COPYING.LIB in the Mercury distribution.
 **
@@ -13,15 +13,15 @@
 
 #include <stdio.h>
 
-#include <mercury_conf.h>
-#include <mercury_types.h>
-#include <mercury_float.h>
+#include "mercury_conf.h"
+#include "mercury_types.h"
+#include "mercury_float.h"
 
 #include "mb_basetypes.h"
 #include "mb_stack.h"
 #include "mb_util.h"
 
-typedef struct MB_Tag_struct {
+typedef struct MB_Tag_Struct {
 	MB_Byte	id;
 	union {
 		MB_Byte	primary;
@@ -56,12 +56,28 @@
 #define	MB_DET_ERRONEOUS		6
 #define	MB_DET_FAILURE			7
 	/*
-	** Invalid is used to indicate that there is something wrong with
-	** this predicate. (Probably contains foreign code) and the bytecode
-	** version should not be used
+	** Unusable is used to indicate that there is something wrong with
+	** this predicate (probably contains foreign code) and the bytecode
+	** version cannot be used
 	*/
-#define	MB_DET_INVALID			99
+#define	MB_DET_UNUSABLE			99
 
+/* Return true if determinism model is the same as that specified */
+#define MB_model_det(x) (\
+	((x) == MB_DET_DET) || \
+	((x) == MB_DET_CC_MULTIDET) || \
+	((x) == MB_DET_ERRONEOUS))
+
+#define MB_model_semi(x) (\
+	((x) == MB_DET_SEMIDET) || \
+	((x) == MB_DET_CC_NONDET) || \
+	((x) == MB_DET_FAILURE))
+
+#define MB_model_nondet(x) (\
+	((x) == MB_DET_NONDET) || \
+	((x) == MB_DET_MULTIDET))
+
+	
 typedef struct MB_Op_arg_struct {
 	MB_Byte	id;
 	union {
@@ -94,12 +110,21 @@
 #define	MB_DIR_TO_VAR		1
 #define	MB_DIR_TO_NONE		2
 
+typedef struct {
+	/* Whether call is a native code call */
+	MB_Bool		is_native;
+	/* code address to call */
+	union {
+		MB_Bytecode_Addr bc;
+		MB_Native_Addr	native;
+	} addr;
+} MB_Code_Addr;
 
 typedef struct MB_Cons_id_struct {
 	MB_Byte	id;
 	union {
 		struct {
-			MB_CString	module_id;
+			MB_CString	module_name;
 			MB_CString	string;
 			MB_Short	arity;
 			MB_Tag		tag;
@@ -108,25 +133,22 @@
 		MB_CString	string_const;
 		MB_Float	float_const;
 		struct {
-			MB_CString	module_id;
-			MB_CString	pred_id;
+			MB_CString	module_name;
+			MB_CString	pred_name;
 			MB_Short	arity;
-			MB_Byte		is_func;
-			MB_Byte		proc_id;
-
-			/* Whether call is a native code call */
-			MB_Byte		is_native;
-			/* code address to call */
-			MB_Word*	adr;
+			MB_Bool		is_func;
+			MB_Byte		mode_num;
+			/* Actual call address */
+			MB_Code_Addr	addr;
 		} pred_const;
 		struct {
-			MB_CString	module_id;
-			MB_CString	pred_id;
+			MB_CString	module_name;
+			MB_CString	pred_name;
 			MB_Short	arity;
-			MB_Byte		proc_id;
+			MB_Byte		mode_num;
 		} code_addr_const;
 		struct {
-			MB_CString	module_id;
+			MB_CString	module_name;
 			MB_CString	type_name;
 			MB_Byte		type_arity;
 		} base_type_info_const;
@@ -149,19 +171,22 @@
 #define	MB_CONSID_CHAR_CONST		7
 
 /*
-** Internal label structure. index is read from the file and translated
-** into adr, which is the actual code address of a label
+** Internal label structure. At load time the index is read from the file
+** and stored. translate_labels translates indexes into actual memory
+** addresses. The module load and label translation functions are the only
+** only functions that should access index, the rest of the program should
+** only use addr.
 */
 typedef union {
 	MB_Short	index;
-	MB_Word*	adr;
+	MB_Bytecode_Addr addr;
 } MB_Label;
 
 typedef union MB_Bytecode_Arg_tag {
 	struct {
 		MB_CString	pred_name;
 		MB_Short	pred_arity;
-		MB_Byte		is_func;
+		MB_Bool		is_func;
 		MB_Short	proc_count;
 	} enter_pred;
 
@@ -169,13 +194,13 @@
 	} endof_pred;
 
 	struct {
-		MB_Byte		proc_id;
+		MB_Byte		mode_num;
 		MB_Determinism	det;
 		MB_Short	label_count;
 		MB_Label	end_label;
 		MB_Short	temp_count;
 		MB_Short	list_length;
-		MB_CString*	var_info;
+		MB_CString	*var_info;
 		
 		/*
 		** index onto label heap for label indexes
@@ -186,7 +211,7 @@
 
 	struct {
 		/* start of proc (not in file) */
-		MB_Word*	proc_start;
+		MB_Bytecode_Addr proc_start;
 	} endof_proc;
 
 	struct {
@@ -293,28 +318,28 @@
 		MB_Short	to_var;
 		MB_Cons_id	consid;
 		MB_Short	list_length;
-		MB_Short*	var_list;
+		MB_Short	*var_list;
 	} construct;
 
 	struct {
 		MB_Short	from_var;
 		MB_Cons_id	consid;
 		MB_Short	list_length;
-		MB_Short*	var_list;
+		MB_Short	*var_list;
 	} deconstruct;
 
 	struct {
 		MB_Short	to_var;
 		MB_Cons_id	consid;
 		MB_Short	list_length;
-		MB_Var_dir*	var_dir;
+		MB_Var_dir	*var_dir;
 	} complex_construct;
 
 	struct {
 		MB_Short	from_var;
 		MB_Cons_id	consid;
 		MB_Short	list_length;
-		MB_Var_dir*	var_dir;
+		MB_Var_dir	*var_dir;
 	} complex_deconstruct;
 
 	struct {
@@ -328,16 +353,13 @@
 	} pickup_arg;
 		
 	struct {
-		MB_CString	module_id;
-		MB_CString	pred_id;
+		MB_CString	module_name;
+		MB_CString	pred_name;
 		MB_Short	arity;
-		MB_Byte		is_func;
-		MB_Byte		proc_id;
-
-		/* Whether call is local (to bytecode) or external */
-		MB_Byte		is_native;
-		/* code address to call (generated when file is loaded) */
-		MB_Word*	adr;
+		MB_Bool		is_func;
+		MB_Byte		mode_num;
+		/* actual call address */
+		MB_Code_Addr	addr;
 	} call;
 
 	struct  {
--- ../bytecode.posted/mb_bytecode.c	Tue Jan 30 14:04:54 2001
+++ mb_bytecode.c	Mon Jan 29 17:49:01 2001
@@ -1,6 +1,6 @@
 
 /*
-** Copyright (C) 1997-2001 The University of Melbourne.
+** Copyright (C) 1997,2000-2001 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
 ** Public License - see the file COPYING.LIB in the Mercury distribution.
 **
@@ -102,7 +102,7 @@
 			MB_Determinism	det;
 			MB_Short	label_count, end_label;
 			MB_Short	temp_count, list_length;
-			MB_CString*	var_info;
+			MB_CString	*var_info;
 			
 			if (MB_read_byte(fp, &proc_id) &&
 				MB_read_byte(fp, &det) &&
@@ -115,7 +115,7 @@
 				MB_CString	str;
 
 				var_info = (list_length == 0) ?  NULL :
-					MB_code_data_alloc(MB_CString,
+					MB_CODE_DATA_ALLOC(MB_CString,
 							list_length); 
 
 				for (i = 0; i < list_length; i++) {
@@ -127,7 +127,7 @@
 					}
 				}
 
-				bc_p->opt.enter_proc.proc_id = proc_id;
+				bc_p->opt.enter_proc.mode_num = proc_id;
 				bc_p->opt.enter_proc.det = det;
 				bc_p->opt.enter_proc.label_count = label_count;
 				bc_p->opt.enter_proc.end_label.index =
@@ -408,7 +408,7 @@
 				MB_Short i;
 
 				var_list = (list_length == 0) ?  NULL : 
-					MB_code_data_alloc(MB_Short,
+					MB_CODE_DATA_ALLOC(MB_Short,
 							list_length);
 
 				for (i = 0; i < list_length; i++) {
@@ -446,7 +446,7 @@
 				MB_Short i;
 
 				var_list = (list_length == 0) ?  NULL : 
-					MB_code_data_alloc(MB_Short,
+					MB_CODE_DATA_ALLOC(MB_Short,
 							list_length);
 
 				for (i = 0; i < list_length; i++) {
@@ -481,11 +481,11 @@
 				MB_read_cons_id(fp, &consid) &&
 				MB_read_short(fp, &list_length))
 			{
-				MB_Var_dir*	var_dir_list;
+				MB_Var_dir	*var_dir_list;
 				MB_Var_dir	var_dir;
 				int		i;
 
-				var_dir_list = MB_code_data_alloc(MB_Var_dir,
+				var_dir_list = MB_CODE_DATA_ALLOC(MB_Var_dir,
 								list_length);
 
 				for (i = 0; i < list_length ; i++) {
@@ -518,11 +518,11 @@
 				MB_read_cons_id(fp, &consid) &&
 				MB_read_short(fp, &list_length))
 			{
-				MB_Var_dir*	var_dir_list;
+				MB_Var_dir	*var_dir_list;
 				MB_Var_dir	var_dir;
 				int		i;
 
-				var_dir_list = MB_code_data_alloc(MB_Var_dir,
+				var_dir_list = MB_CODE_DATA_ALLOC(MB_Var_dir,
 								list_length);
 
 				for (i = 0; i < list_length; i++) {
@@ -592,16 +592,20 @@
 				MB_read_byte(fp, &is_func) &&
 				MB_read_byte(fp, &proc_id))
 			{
-				bc_p->opt.call.module_id =
+				bc_p->opt.call.module_name =
 					module_id;
-				bc_p->opt.call.pred_id =
+				bc_p->opt.call.pred_name =
 					pred_id;
 				bc_p->opt.call.arity = arity;
 				bc_p->opt.call.is_func = is_func;
-				bc_p->opt.call.proc_id = proc_id;
+				bc_p->opt.call.mode_num = proc_id;
 
-				bc_p->opt.call.is_native = TRUE;
-				bc_p->opt.call.adr = NULL;
+				/*
+				** Initialise code address to invalid in case
+				** it somehow gets executed
+				*/
+				bc_p->opt.call.addr.is_native = FALSE;
+				bc_p->opt.call.addr.addr.bc = MB_CODE_INVALID_ADR;
 				return TRUE;
 			} else {
 				MB_fatal("call read error");
@@ -905,53 +909,69 @@
 /*
 ** Returned string is allocated with string routines MB_str_xxx
 ** It is the responsibility of the caller to free it using MB_str_delete
-**
-** Will read from the file a complete string, but will only store in
-** memory string of maximum size of buffer below
 */
 static MB_Bool
 MB_read_cstring(FILE *fp, MB_CString *str_p)
 {
 	/*
-	** reads in string BUFSIZE characters at a time and when buffer
-	** is full or the end is encountered, allocates space for the string.
-	** If the string is longer than BUFSIZE chars, the rest is ignored.
+	** Initially tries to read string into buffer, but if this gets
+	** full then mallocs another buffer which is doubled in size
+	** whenever it gets full.
+	** Returned string is allocated with MB_str_dup
 	*/
-	char	buffer[127];
-	char*	str = buffer;
+	char	buffer[64];
+	MB_Word	bufsize = sizeof(buffer);
+	char	*str = buffer;
 	
-	int		i = 0;
+	MB_Word		i = 0;
 	MB_Byte		c;
 	
-	for (i=0;;) {
+	do {
 		/* get the next char */
 		if (!MB_read_byte(fp, &c)) {
 			MB_fatal("Error reading C String from file");
 		}
 
-		/* If we haven't yet filled the buffer*/
-		if (i < sizeof(buffer)) {
-			if (c) {
-				str[i] = c;
-				i++;
-				/* Save the string if we filled the buffer */
-				if (i == sizeof(buffer)-1) {
-					buffer[sizeof(buffer)-1] = 0;
-					*str_p = MB_str_dup(buffer);
-				}
+		/*
+		** If the next char is going to overflow the buffer then
+		** expand the buffer
+		*/
+		if (i == bufsize) {
+			/* Double the size of the buffer */
+			bufsize *= 2;
+			
+			if (str == buffer) {
+				/*
+				** If we are still using the stack buffer,
+				** allocate a new buffer with malloc
+				*/
+				str = MB_malloc(bufsize);
+				memcpy(str, buffer, bufsize/2);
 			} else {
-				str[i] = 0;
-				*str_p = MB_str_dup(buffer);
-				return TRUE;
+				/*
+				** The current buffer is already malloced;
+				** realloc it
+				*/
+				str = MB_realloc(str, bufsize);
 			}
-		} else if (!c) {
-			/* Otherwise, continue until we get a null terminator*/
-			return TRUE;
+
+			if (str == NULL) return FALSE;
 		}
-	} /* end for */
 
-	assert(FALSE);
+		str[i++] = c;
+
+	} while (c != 0);
 
+	if ((*str_p = MB_str_dup(str)) == NULL) {
+		return FALSE;
+	}
+
+	/* Free the string if it isn't on the local stack */
+	if (str != buffer) {
+		MB_free(str);
+	}
+
+	return TRUE;
 } /* end MB_read_cstring() */
 
 
@@ -980,7 +1000,7 @@
 				MB_read_short(fp, &arity) &&
 				MB_read_tag(fp, &tag))
 			{
-				cons_id_p->opt.cons.module_id = module_id;
+				cons_id_p->opt.cons.module_name = module_id;
 				cons_id_p->opt.cons.string = string;
 				cons_id_p->opt.cons.arity = arity;
 				cons_id_p->opt.cons.tag = tag;
@@ -1044,11 +1064,11 @@
 				MB_read_byte(fp, &is_func) &&
 				MB_read_byte(fp, &proc_id))
 			{
-				cons_id_p->opt.pred_const.module_id = module_id;
-				cons_id_p->opt.pred_const.pred_id = pred_id;
+				cons_id_p->opt.pred_const.module_name=module_id;
+				cons_id_p->opt.pred_const.pred_name = pred_id;
 				cons_id_p->opt.pred_const.arity = arity;
 				cons_id_p->opt.pred_const.is_func = is_func;
-				cons_id_p->opt.pred_const.proc_id = proc_id;
+				cons_id_p->opt.pred_const.mode_num = proc_id;
 				return TRUE;
 			} else {
 				MB_util_error("Unable to read predicate"
@@ -1069,12 +1089,12 @@
 				MB_read_short(fp, &arity) &&
 				MB_read_byte(fp, &proc_id))
 			{
-				cons_id_p->opt.code_addr_const.module_id = 
+				cons_id_p->opt.code_addr_const.module_name = 
 					module_id;
-				cons_id_p->opt.code_addr_const.pred_id =
+				cons_id_p->opt.code_addr_const.pred_name =
 					pred_id;
 				cons_id_p->opt.code_addr_const.arity = arity;
-				cons_id_p->opt.code_addr_const.proc_id =
+				cons_id_p->opt.code_addr_const.mode_num =
 					proc_id;
 				return TRUE;
 			} else {
@@ -1093,8 +1113,8 @@
 				MB_read_cstring(fp, &type_name) && 
 				MB_read_byte(fp, &type_arity)) 
 			{
-				cons_id_p->opt.base_type_info_const.module_id = 
-					module_id;
+				cons_id_p->opt.base_type_info_const.module_name
+					= module_id;
 				cons_id_p->opt.base_type_info_const.type_name = 
 					type_name;
 				cons_id_p->opt.base_type_info_const.type_arity =
@@ -1200,7 +1220,7 @@
 			break;
 	} /* switch */
 
-	assert(FALSE);	/* not reached*/
+	assert(FALSE);	/* not reached */
 	return FALSE;
 } /* end MB_read_tag() */
 
@@ -1278,7 +1298,7 @@
 			return FALSE;
 	} /* end switch */
 
-	assert(FALSE);	/* not reached*/
+	assert(FALSE);	/* not reached */
 	return FALSE;
 } /* end MB_read_op_arg() */
 
--- ../bytecode.posted/mb_disasm.h	Tue Jan 30 14:04:54 2001
+++ mb_disasm.h	Mon Jan 29 18:46:58 2001
@@ -1,6 +1,6 @@
 
 /*
-** Copyright (C) 1997-2001 The University of Melbourne.
+** Copyright (C) 1997,2000-2001 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
 ** Public License - see the file COPYING.LIB in the Mercury distribution.
 **
@@ -19,12 +19,20 @@
 ** Fills a string buffer with the name of a bytecode (if buffer_len > 0)
 ** Returns the new indent level after the instruction
 */
-int MB_str_bytecode(MB_Machine_State* module, MB_Word* adr, char* buffer,
+int MB_str_bytecode(MB_Machine_State *module, MB_Bytecode_Addr addr, char
*buffer,
 		int buffer_len, int indent_level);
 
 /* displays a code listing (see source file for argument description) */
-void MB_listing(MB_Machine_State*ms, FILE* fp, MB_Word* start, MB_Word* end,
-		MB_Word line_len);
+void MB_listing(MB_Machine_State *ms, FILE *fp, MB_Bytecode_Addr start,
+	MB_Bytecode_Addr end, MB_Word line_len);
+
+/* XXX: width fields below may not be correct for all platforms */
+/* printf Format string specifiers */
+#define MB_FMT_INT	"% 11" MR_INTEGER_LENGTH_MODIFIER "d"
+#define MB_FMT_HEX	"0x%08" MR_INTEGER_LENGTH_MODIFIER "x"
+
+/* XXX: No string for 'MB_Short's. For now promote to int and use %d */
+/* XXX: No string for 'MB_Byte's. For now promote to int and use %d */
 
 #endif	/* MB_DISASM_H */
 
--- ../bytecode.posted/mb_disasm.c	Tue Jan 30 14:04:54 2001
+++ mb_disasm.c	Tue Jan 30 16:55:28 2001
@@ -1,6 +1,6 @@
 
 /*
-** Copyright (C) 1997-2001 The University of Melbourne.
+** Copyright (C) 1997,2000-2001 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
 ** Public License - see the file COPYING.LIB in the Mercury distribution.
 **
@@ -8,10 +8,6 @@
 **
 */
 
-/* XXX: the format strings used below assume that MB_Word is an int and
-** that casting MB_Word to int for printing will produce no strange effects
-*/
-
 /* Imports */
 #include	<assert.h>
 #include	<ctype.h>
@@ -19,64 +15,66 @@
 #include	<stdio.h>
 
 #include	"mb_disasm.h"
+#include	"mb_module.h"
 #include	"mb_util.h"
+
 #include	"mb_machine_def.h"
 
 /* Exported definitions */
 
-int MB_str_bytecode(MB_Machine_State* ms, MB_Word* adr,
-		char* buffer, int buffer_len, int indent_level);
+int MB_str_bytecode(MB_Machine_State *ms, MB_Bytecode_Addr addr,
+		char *buffer, int buffer_len, int indent_level);
 
-void MB_listing(MB_Machine_State* ms, FILE* fp, MB_Word* start, MB_Word* end,
-		MB_Word line_len);
+void MB_listing(MB_Machine_State *ms, FILE *fp, MB_Bytecode_Addr start,
+	MB_Bytecode_Addr end, MB_Word line_len);
 
 /* Local declarations */
 
 /* Fills a c string buffer with to the name of a constructor id */
-static void str_cons_id(MB_Cons_id cons_id, char* buffer, int buffer_len);
+static void str_cons_id(MB_Cons_id cons_id, char *buffer, int buffer_len);
 
 /* Fills a c string buffer with to the name of a tag */
-static void str_tag(MB_Tag tag, char* buffer, int buffer_len);
+static void str_tag(MB_Tag tag, char *buffer, int buffer_len);
 
 /* Returns a string corresponding to the name of a bytecode type */
-static const MB_CString str_bytecode_name(MB_Byte bytecode_id);
+static MB_CString_Const str_bytecode_name(MB_Byte bytecode_id);
 
 /* Returns a string corresponding to the name of a determinism type */
-static const MB_CString str_determinism_name(MB_Byte determinism_id);
+static MB_CString_Const str_determinism_name(MB_Byte determinism_id);
 
 /* Returns a string corresponding to the name of a unary operation */
-static const MB_CString str_unop_name(MB_Byte unop);
+static MB_CString_Const str_unop_name(MB_Byte unop);
 
 /* Returns a string corresponding to the name of a binary operation */
-static const MB_CString str_binop_name(MB_Byte binop);
+static MB_CString_Const str_binop_name(MB_Byte binop);
 
 /* Fills a buffer with a string transformed into a source-style c string 
  * (includes double quotes around string) */
-static void quote_cstring(MB_CString str, char* buffer, int buffer_len);
+static void quote_cstring(MB_CString str, char *buffer, int buffer_len);
 
 /* Fills a c string buffer with a variable list */
-static void str_var_dir(MB_Var_dir var_dir, char* buffer, int buffer_len);
+static void str_var_dir(MB_Var_dir var_dir, char *buffer, int buffer_len);
 
 /* Fills a c string buffer with an operation argument */
-static void str_op_arg(MB_Op_arg op_arg, char* buffer, int buffer_len);
+static void str_op_arg(MB_Op_arg op_arg, char *buffer, int buffer_len);
 
 /* Implementation */
 
 
-/* Macros for printing:
-** expects buffer, buffer_len & last_len to be defined
-** (My kingdom for a C++ stream!)
-** wraps calls to snprintf, checks if the buffer is full and
+/*
+** Macros for printing:
+** Expects buffer, buffer_len & last_len to be defined.
+** Wraps calls to snprintf, checks if the buffer is full and
 ** if it is, returns from the function
 */
 
-#define Print()		if (buffer_len > 1) { \
+#define PRINT()		if (buffer_len > 1) { \
 				int last_len; \
 				assert(buffer_len > 0); \
 				last_len = snprintf(buffer, buffer_len,
 
 /* printf arguments get sandwiched between these macros */
-#define EndPrint()				);	\
+#define ENDPRINT()				);	\
 				if (last_len >= buffer_len) {\
 					last_len = buffer_len-1; \
 				} \
@@ -92,38 +90,42 @@
 			}
 
 
-/* Call this after calling a function that has added characters to the buffer
*/
-/* -> Requires that if the function filled the buffer, it must have at least */
-/* put a null terminator at the end */
-#define PrintFillCheck() {	\
+/*
+** Call this after calling a function that has added characters to the buffer
+** Requires that if the function filled the buffer, it must have at least
+** put a null terminator at the end
+*/
+#define PRINTFILLCHECK() {	\
 				int str_len = strlen(buffer);	\
 				buffer += str_len;		\
 				buffer_len -= str_len;		\
 				assert(buffer_len > 0); \
 			}
 
-/* Macro to call a function of the format f(arg, buffer, buffer_len)
- * where the function fills all or part of the buffer
- */
-#define PrintCall(x, y)	(x)((y), buffer, buffer_len); \
-			PrintFillCheck()
+/*
+** Macro to call a function of the format f(arg, buffer, buffer_len)
+** where the function fills all or part of the buffer
+*/
+#define PRINTCALL(x, y)	(x)((y), buffer, buffer_len); \
+			PRINTFILLCHECK()
+
 /*
 ** Fills a string corresponding to a bytecode
-** returns indent level for subsequent instructions
+** Returns indent level for subsequent instructions
 **
-** if buffer is NULL or buffer_len is <= 0 then only returns
+** If buffer is NULL or buffer_len is <= 0 then only returns
 **  new indent level
 **
-** The general convention is for arguments to be in square brackets
-** and calculated arguments (ie not in the bytecode file) in round brackets
+** The general convention is for arguments to be in square brackets and
+** calculated arguments (ie not in the bytecode file) in round brackets
 */
 
 int
-MB_str_bytecode(MB_Machine_State* ms, MB_Word* adr, char* buffer,
+MB_str_bytecode(MB_Machine_State *ms, MB_Bytecode_Addr addr, char *buffer,
 		int buffer_len, int indent_level)
 {
-	MB_Byte bc_id = MB_code_get_id(adr);
-	MB_Bytecode_Arg* bca = MB_code_get_arg(adr);
+	MB_Byte bc_id = MB_code_get_id(addr);
+	MB_Bytecode_Arg *bca = MB_code_get_arg(addr);
 
 	/* calculate indent changes */
 	int this_indent = indent_level;
@@ -193,35 +195,35 @@
 	
 	/* indicate det/nondet code */
 	/* 
-	Print()
+	PRINT()
 		"%c",
-		(MB_code_get_det(adr) ? '+' : '-')
-	EndPrint()
+		(MB_code_get_det(addr) ? '+' : '-')
+	ENDPRINT()
 	*/
 
 	
 	/* print the indents */
 	while (this_indent > 0) {
-		Print()
+		PRINT()
 			"   "
-		EndPrint()
+		ENDPRINT()
 		this_indent--;
 	}
 	
-	Print()
+	PRINT()
 		"%s",
 		str_bytecode_name(bc_id)
-	EndPrint()
+	ENDPRINT()
 
 	switch (bc_id) {
 		case MB_BC_enter_pred:
-			Print()
+			PRINT()
 				" %s %s/%d (%d procs)",
 				bca->enter_pred.is_func ? "func" : "pred",
 				bca->enter_pred.pred_name,
-				(int)bca->enter_pred.pred_arity,
-				(int)bca->enter_pred.proc_count
-			EndPrint()
+				(int) bca->enter_pred.pred_arity,
+				(int) bca->enter_pred.proc_count
+			ENDPRINT()
 			break;
 				
 		case MB_BC_endof_pred:
@@ -233,46 +235,46 @@
 			MB_Short	i;
 			MB_Short	len;
 			
-			Print()
-				" proc %d: [%s] [%d labels] [endlabel %p]"
+			PRINT()
+				" mode %d: [%s] [%d labels] [endlabel %p]"
 					" [%d temps] [%d vars]", 
-				(int)bca->enter_proc.proc_id,
+				(int) bca->enter_proc.mode_num,
 				str_determinism_name(bca->enter_proc.det),
-				(int)bca->enter_proc.label_count,
-				bca->enter_proc.end_label.adr,
-				(int)bca->enter_proc.temp_count,
-				(int)bca->enter_proc.list_length
-			EndPrint()
+				bca->enter_proc.label_count,
+				bca->enter_proc.end_label.addr,
+				bca->enter_proc.temp_count,
+				bca->enter_proc.list_length
+			ENDPRINT()
 
 			len = bca->enter_proc.list_length;
 			for (i = 0; i < len; i++) {
-				Print()
+				PRINT()
 					" %s",
 					bca->enter_proc.var_info[i]
 
-				EndPrint()
+				ENDPRINT()
 			}
 			break;
 		}
 		case MB_BC_endof_proc:
-			Print()
+			PRINT()
 				" (%p)",
 				bca->endof_proc.proc_start
-			EndPrint()
+			ENDPRINT()
 			break;
 			
 		case MB_BC_label:
-			Print()
+			PRINT()
 				" %d",
-				(int)bca->label.label
-			EndPrint()
+				(int) bca->label.label
+			ENDPRINT()
 			break;
 				
 		case MB_BC_enter_disjunction:
-			Print()
+			PRINT()
 				" [endlabel %p]",
-				bca->enter_disjunction.end_label.adr
-			EndPrint()
+				bca->enter_disjunction.end_label.addr
+			ENDPRINT()
 			break;
 				
 		case MB_BC_endof_disjunction:
@@ -281,25 +283,25 @@
 			break;
 			
 		case MB_BC_enter_disjunct:
-			Print()
+			PRINT()
 				" [nextlabel %p]",
-				bca->enter_disjunct.next_label.adr
-			EndPrint()
+				bca->enter_disjunct.next_label.addr
+			ENDPRINT()
 			break;
 				
 		case MB_BC_endof_disjunct:
-			Print()
+			PRINT()
 				" [endlabel %p]",
-				bca->endof_disjunct.end_label.adr
-			EndPrint()
+				bca->endof_disjunct.end_label.addr
+			ENDPRINT()
 			break;
 				
 		case MB_BC_enter_switch:
-			Print()
+			PRINT()
 				" [var %d] [endlabel %p]",
-				bca->enter_switch.var,
-				bca->enter_switch.end_label.adr
-			EndPrint()
+				(int) bca->enter_switch.var,
+				bca->enter_switch.end_label.addr
+			ENDPRINT()
 			break;
 				
 		case MB_BC_endof_switch:
@@ -308,54 +310,54 @@
 			break;
 			
 		case MB_BC_enter_switch_arm:
-			Print()
+			PRINT()
 				" (on var %d) ",
-				(int)bca->enter_switch_arm.var
-			EndPrint()
+				(int) bca->enter_switch_arm.var
+			ENDPRINT()
 
-			PrintCall(str_cons_id, bca->enter_switch_arm.cons_id)
+			PRINTCALL(str_cons_id, bca->enter_switch_arm.cons_id)
 
-			Print()
+			PRINT()
 				" [nextlabel %p]",
-				bca->enter_switch_arm.next_label.adr
-			EndPrint()
+				bca->enter_switch_arm.next_label.addr
+			ENDPRINT()
 			break;
 				
 		case MB_BC_endof_switch_arm:
-			Print()
+			PRINT()
 				" [endlabel %p]",
-				bca->endof_switch_arm.end_label.adr
-			EndPrint()
+				bca->endof_switch_arm.end_label.addr
+			ENDPRINT()
 			break;
 				
 		case MB_BC_enter_if:
-			Print()
+			PRINT()
 				" [else %p] [end %p] [frame %d]",
-				bca->enter_if.else_label.adr,
-				bca->enter_if.end_label.adr,
-				(int)bca->enter_if.frame_ptr_tmp
-			EndPrint()
+				bca->enter_if.else_label.addr,
+				bca->enter_if.end_label.addr,
+				(int) bca->enter_if.frame_ptr_tmp
+			ENDPRINT()
 			break;
 				
 		case MB_BC_enter_then:
-			Print()
+			PRINT()
 				" [frame %d]",
-				(int)bca->enter_then.frame_ptr_tmp
-			EndPrint()
+				(int) bca->enter_then.frame_ptr_tmp
+			ENDPRINT()
 			break;
 				
 		case MB_BC_endof_then:
-			Print()
+			PRINT()
 				" [follow %p]",
-				bca->endof_then.follow_label.adr
-			EndPrint()
+				bca->endof_then.follow_label.addr
+			ENDPRINT()
 			break;
 
 		case MB_BC_enter_else:
-			Print()
+			PRINT()
 				" [frame %d]",
-				(int)bca->enter_else.frame_ptr_tmp
-			EndPrint()
+				(int) bca->enter_else.frame_ptr_tmp
+			ENDPRINT()
 			break;
 
 				
@@ -365,18 +367,18 @@
 			break;
 			
 		case MB_BC_enter_negation:
-			Print()
+			PRINT()
 				" [frame %d] [endlabel %p]",
-				(int)bca->enter_negation.frame_ptr_tmp,
-				bca->enter_negation.end_label.adr
-			EndPrint()
+				(int) bca->enter_negation.frame_ptr_tmp,
+				bca->enter_negation.end_label.addr
+			ENDPRINT()
 			break;
 
 		case MB_BC_endof_negation_goal:
-			Print()
+			PRINT()
 				" [frame %d]",
-				(int)bca->endof_negation_goal.frame_ptr_tmp
-			EndPrint()
+				(int) bca->endof_negation_goal.frame_ptr_tmp
+			ENDPRINT()
 				
 		case MB_BC_endof_negation:
 			/* No args */
@@ -384,119 +386,119 @@
 			break;
 			
 		case MB_BC_enter_commit:
-			Print()
+			PRINT()
 				" [frame %d]",
-				(int)bca->enter_commit.frame_ptr_tmp
-			EndPrint()
+				(int) bca->enter_commit.frame_ptr_tmp
+			ENDPRINT()
 			break;
 				
 		case MB_BC_endof_commit:
-			Print()
+			PRINT()
 				" [frame %d]",
-				(int)bca->endof_commit.frame_ptr_tmp
-			EndPrint()
+				(int) bca->endof_commit.frame_ptr_tmp
+			ENDPRINT()
 			break;
 				
 		case MB_BC_assign:
-			Print()
+			PRINT()
 				" [var %d] <= [var %d]",
-				(int)bca->assign.to_var,
-				(int)bca->assign.from_var
-			EndPrint()
+				(int) bca->assign.to_var,
+				(int) bca->assign.from_var
+			ENDPRINT()
 			break;
 				
 		case MB_BC_test:
-			Print()
+			PRINT()
 				" [var %d] == [var %d]",
-				(int)bca->test.var1,
-				(int)bca->test.var2
-			EndPrint()
+				(int) bca->test.var1,
+				(int) bca->test.var2
+			ENDPRINT()
 			break;
 				
 		case MB_BC_construct: {
 			MB_Short	len;
 			MB_Short	i;
 
-			Print()
+			PRINT()
 				" [var %d] <= ",
-				(int)bca->construct.to_var
-			EndPrint()
+				(int) bca->construct.to_var
+			ENDPRINT()
 
-			PrintCall(str_cons_id,bca->construct.consid)
+			PRINTCALL(str_cons_id,bca->construct.consid)
 
 			len = bca->construct.list_length;
-			Print()
+			PRINT()
 				" [%d var%s%s",
-				(int)len,
+				(int) len,
 				(len != 0) ? "s" : "",
 				(len > 0)  ? ":" : ""
-			EndPrint()
+			ENDPRINT()
 			for (i = 0; i < len; i++) {
-				Print()
+				PRINT()
 					" %d",
-					(int)bca->construct.var_list[i]
-				EndPrint()
+					(int) bca->construct.var_list[i]
+				ENDPRINT()
 				
 			}
-			Print()
+			PRINT()
 				"]"
-			EndPrint()
+			ENDPRINT()
 			break;
 		}
 		case MB_BC_deconstruct: {
 			MB_Short	len;
 			MB_Short	i;
 
-			Print()
+			PRINT()
 				" [var %d] ",
-				(int)bca->deconstruct.from_var
-			EndPrint()
+				(int) bca->deconstruct.from_var
+			ENDPRINT()
 			
-			PrintCall(str_cons_id,bca->deconstruct.consid)
+			PRINTCALL(str_cons_id,bca->deconstruct.consid)
 
 			len = bca->deconstruct.list_length;
-			Print()
+			PRINT()
 				" [%d var%s%s",
-				(int)len,
+				(int) len,
 				(len != 0) ? "s" : "",
 				(len > 0)  ? ":" : ""
-			EndPrint()
+			ENDPRINT()
 
 			for (i = 0; i < len; i++) {
-				Print()
+				PRINT()
 					" %d",
-					(int)bca->deconstruct.var_list[i]
-				EndPrint()
+					(int) bca->deconstruct.var_list[i]
+				ENDPRINT()
 				
 			}
-			Print()
+			PRINT()
 				"]"
-			EndPrint()
+			ENDPRINT()
 			break;
 		}
 		case MB_BC_complex_construct: {
 			MB_Short	len;
 			MB_Short	i;
 
-			Print()
+			PRINT()
 				" %d ",
-				(int)bca->complex_construct.to_var
-			EndPrint()
+				(int) bca->complex_construct.to_var
+			ENDPRINT()
 
-			PrintCall(str_cons_id,bca->complex_construct.consid);
+			PRINTCALL(str_cons_id,bca->complex_construct.consid);
 
 			len = bca->complex_construct.list_length;
 			
-			Print()
-				" %d", (int)len
-			EndPrint()
+			PRINT()
+				" %d", (int) len
+			ENDPRINT()
 
 			for (i = 0; i < len; i++) {
-				Print()
+				PRINT()
 					" "
-				EndPrint()
+				ENDPRINT()
 
-				PrintCall(str_var_dir,
+				PRINTCALL(str_var_dir,
 					bca->complex_construct.var_dir[i])
 			}
 			break;
@@ -505,124 +507,126 @@
 			MB_Short	len;
 			MB_Short	i;
 
-			Print()
+			PRINT()
 				" %d ",
-				(int)bca->complex_deconstruct.from_var
-			EndPrint()
+				(int) bca->complex_deconstruct.from_var
+			ENDPRINT()
 
-			PrintCall(str_cons_id,bca->complex_deconstruct.consid);
+			PRINTCALL(str_cons_id,bca->complex_deconstruct.consid)
 
 			len = bca->complex_deconstruct.list_length;
-			Print()
+			PRINT()
 				" %d",
-				(int)len
-			EndPrint()
+				(int) len
+			ENDPRINT()
 
 			for (i = 0; i < len; i++) {
-				Print()
+				PRINT()
 					" "
-				EndPrint()
+				ENDPRINT()
 
-				PrintCall(str_var_dir,
+				PRINTCALL(str_var_dir,
 					bca->complex_deconstruct.var_dir[i])
 			}
 			break;
 		}
 		case MB_BC_place_arg:
-			Print()
+			PRINT()
 				" [r%d] <= [var %d]",
-				(int)bca->place_arg.to_reg,
-				(int)bca->place_arg.from_var
-			EndPrint()
+				(int) bca->place_arg.to_reg,
+				(int) bca->place_arg.from_var
+			ENDPRINT()
 			break;
 				
 		case MB_BC_pickup_arg:
-			Print()
+			PRINT()
 				" [r%d] => [var %d]",
-				(int)bca->pickup_arg.from_reg,
-				(int)bca->pickup_arg.to_var
-			EndPrint()
+				(int) bca->pickup_arg.from_reg,
+				(int) bca->pickup_arg.to_var
+			ENDPRINT()
 			break;
 				
 		case MB_BC_call:
-			Print()
-				" [%s %s__%s/%d] [proc %d (%s %p)]",
+			PRINT()
+				" [%s %s__%s/%d mode %d (%s %p)]",
 				bca->call.is_func ? "func" : "pred",
-				bca->call.module_id,
-				bca->call.pred_id,
-				(int)bca->call.arity,
-				(int)bca->call.proc_id,
-				bca->call.is_native ? "natv" : "byte",
-				bca->call.adr
-			EndPrint()
+				bca->call.module_name,
+				bca->call.pred_name,
+				(int) bca->call.arity,
+				(int) bca->call.mode_num,
+				bca->call.addr.is_native ? "natv" : "byte",
+				bca->call.addr.is_native ?
+				 	(MB_Word *) bca->call.addr.addr.native :
+					(MB_Word *) bca->call.addr.addr.bc
+			ENDPRINT()
 			break;
 				
 		case MB_BC_higher_order_call:
-			Print()
+			PRINT()
 				" [var %d] [invars %d] [outvars %d] [%s]",
-				(int)bca->higher_order_call.pred_var,
-				(int)bca->higher_order_call.in_var_count,
-				(int)bca->higher_order_call.out_var_count,
+				(int) bca->higher_order_call.pred_var,
+				(int) bca->higher_order_call.in_var_count,
+				(int) bca->higher_order_call.out_var_count,
 				str_determinism_name(bca->higher_order_call.det)
-			EndPrint()
+			ENDPRINT()
 			break;
 				
 		case MB_BC_builtin_binop:
-			Print()
+			PRINT()
 				": "
-			EndPrint()
+			ENDPRINT()
 
-			PrintCall(str_op_arg,bca->builtin_binop.arg1)
+			PRINTCALL(str_op_arg,bca->builtin_binop.arg1)
 
-			Print()
+			PRINT()
 				" %s ", 
 				str_binop_name(bca->builtin_binop.binop)
-			EndPrint()
+			ENDPRINT()
 
-			PrintCall(str_op_arg,bca->builtin_binop.arg2)
+			PRINTCALL(str_op_arg,bca->builtin_binop.arg2)
 
-			Print()
+			PRINT()
 				" => [var %d]",
-				(int)bca->builtin_binop.to_var
-			EndPrint()
+				(int) bca->builtin_binop.to_var
+			ENDPRINT()
 			break;
 				
 		case MB_BC_builtin_unop:
-			Print()
+			PRINT()
 				" %s ", 
 				str_unop_name(bca->builtin_unop.unop)
-			EndPrint()
+			ENDPRINT()
 
-			PrintCall(str_op_arg,bca->builtin_unop.arg)
+			PRINTCALL(str_op_arg,bca->builtin_unop.arg)
 
-			Print()
+			PRINT()
 				" %d",
-				(int)bca->builtin_unop.to_var
-			EndPrint()
+				(int) bca->builtin_unop.to_var
+			ENDPRINT()
 			break;
 				
 		case MB_BC_builtin_bintest:
 
-			Print()
+			PRINT()
 				" "
-			EndPrint()
+			ENDPRINT()
 
-			PrintCall(str_op_arg,bca->builtin_binop.arg1)
+			PRINTCALL(str_op_arg,bca->builtin_binop.arg1)
 
-			Print()
+			PRINT()
 				" %s ", 
 				str_binop_name(bca->builtin_bintest.binop)
-			EndPrint()
+			ENDPRINT()
 
-			PrintCall(str_op_arg,bca->builtin_binop.arg2)
+			PRINTCALL(str_op_arg,bca->builtin_binop.arg2)
 			break;
 				
 		case MB_BC_builtin_untest:
-			Print()
+			PRINT()
 				" %s ", 
 				str_unop_name(bca->builtin_untest.unop)
-			EndPrint()
-			PrintCall(str_op_arg,bca->builtin_unop.arg)
+			ENDPRINT()
+			PRINTCALL(str_op_arg,bca->builtin_unop.arg)
 			break;
 				
 		case MB_BC_semidet_succeed:
@@ -641,10 +645,10 @@
 			break;
 			
 		case MB_BC_context:
-			Print()
+			PRINT()
 				" %d",
 				bca->context.line_number
-			EndPrint()
+			ENDPRINT()
 			break;
 				
 		case MB_BC_not_supported:
@@ -662,102 +666,110 @@
 } /* end print_bytecode() */
 
 static void
-str_cons_id(MB_Cons_id cons_id, char* buffer, int buffer_len)
+str_cons_id(MB_Cons_id cons_id, char *buffer, int buffer_len)
 {
-	Print()
+	PRINT()
 		"["
-	EndPrint()
+	ENDPRINT()
 	switch (cons_id.id) {
 		case MB_CONSID_CONS: {
-			Print()
+			PRINT()
 				"functor %s__%s/%d ",
-				cons_id.opt.cons.module_id,
+				cons_id.opt.cons.module_name,
 				cons_id.opt.cons.string,
-				(int)cons_id.opt.cons.arity
-			EndPrint()
-			PrintCall(str_tag, cons_id.opt.cons.tag)
+				(int) cons_id.opt.cons.arity
+			ENDPRINT()
+			PRINTCALL(str_tag, cons_id.opt.cons.tag)
 			break;
 		}
 		case MB_CONSID_INT_CONST:
-			Print()
-				"int_const %x",
-				(int)cons_id.opt.int_const
-			EndPrint()
+			PRINT()
+				"int_const " MB_FMT_INT " (" MB_FMT_HEX ")",
+				cons_id.opt.int_const,
+				cons_id.opt.int_const
+			ENDPRINT()
 			break;
 		case MB_CONSID_STRING_CONST: {
-			Print()
+			PRINT()
 				"string_const"
-			EndPrint()
-			buffer[buffer_len-1] = 0; /* snprintf may not do it */
+			ENDPRINT()
 
-			PrintCall(quote_cstring, cons_id.opt.string_const);
+			PRINTCALL(quote_cstring, cons_id.opt.string_const);
 			break;
 		}
 		case MB_CONSID_FLOAT_CONST:
-			Print()
+			PRINT()
 				"float_const %.15g",
 				cons_id.opt.float_const
-			EndPrint()
+			ENDPRINT()
 			break;
 		case MB_CONSID_PRED_CONST:
-			Print()
-				"%s %s %s__%s/%d proc %d (%p)",
+			PRINT()
+				"%s %s %s__%s/%d mode %d (%s %p)",
 				"pred_const",
 				cons_id.opt.pred_const.is_func ?"func":"pred",
-				cons_id.opt.pred_const.module_id,
-				cons_id.opt.pred_const.pred_id,
-				(int)cons_id.opt.pred_const.arity,
-				(int)cons_id.opt.pred_const.proc_id,
-				cons_id.opt.pred_const.adr
-			EndPrint()
+				cons_id.opt.pred_const.module_name,
+				cons_id.opt.pred_const.pred_name,
+				(int) cons_id.opt.pred_const.arity,
+				(int) cons_id.opt.pred_const.mode_num,
+				cons_id.opt.pred_const.addr.is_native
+					? "natv" : "byte",
+				cons_id.opt.pred_const.addr.is_native
+					? (MB_Word *) cons_id.opt.pred_const
+							.addr.addr.native
+					: (MB_Word *) cons_id.opt.pred_const
+							.addr.addr.bc
+			ENDPRINT()
 			break;
 		case MB_CONSID_CODE_ADDR_CONST:
-			Print()
+			PRINT()
 				"%s %s %s %d %d",
 				"code_addr_const",
-				cons_id.opt.code_addr_const.module_id,
-				cons_id.opt.code_addr_const.pred_id,
-				(int)cons_id.opt.code_addr_const.arity,
-				(int)cons_id.opt.code_addr_const.proc_id
-			EndPrint()
+				cons_id.opt.code_addr_const.module_name,
+				cons_id.opt.code_addr_const.pred_name,
+				(int) cons_id.opt.code_addr_const.arity,
+				(int) cons_id.opt.code_addr_const.mode_num
+			ENDPRINT()
 			break;
 		case MB_CONSID_BASE_TYPE_INFO_CONST:
-			Print()
+			PRINT()
 				"%s %s__%s/%d",
 				"base_type_info_const",
-				cons_id.opt.base_type_info_const.module_id,
+				cons_id.opt.base_type_info_const.module_name,
 				cons_id.opt.base_type_info_const.type_name,
-				(int)cons_id.opt.base_type_info_const.type_arity
-			EndPrint()
+				(int) cons_id.opt.base_type_info_const
+								.type_arity
+			ENDPRINT()
 			break;
 		case MB_CONSID_CHAR_CONST:
 			if (isprint(cons_id.opt.char_const.ch)) {
-				Print()
+				PRINT()
 					"%s '%c'",
 					"char_const",
 					cons_id.opt.char_const.ch
-				EndPrint()
+				ENDPRINT()
 			} else {
-				Print()
-					"%s %2X",
+				PRINT()
+					"%s %d (0x%02X)",
 					"char_const",
-					(int)cons_id.opt.char_const.ch
-				EndPrint()
+					(int) cons_id.opt.char_const.ch,
+					(int) cons_id.opt.char_const.ch
+				ENDPRINT()
 			}
 			break;
 		default:
 			MB_fatal("Attempt to disassemble unknown cons");
 			break;
 	} /* end switch */
-	Print()
+	PRINT()
 		"]"
-	EndPrint()
+	ENDPRINT()
 
 	buffer[buffer_len-1] = 0; /* snprintf may not do it if a long string */
 } /* end print_cons_id() */
 
 static void
-str_tag(MB_Tag tag, char* buffer, int buffer_len)
+str_tag(MB_Tag tag, char *buffer, int buffer_len)
 {
 	
 	switch (tag.id) {
@@ -765,27 +777,27 @@
 			snprintf(buffer, buffer_len,
 				"%s %d",
 				"simple_tag",
-				(int)tag.opt.primary);
+				(int) tag.opt.primary);
 			break;
 		case MB_TAG_COMPLICATED:
 			snprintf(buffer, buffer_len,
 				"%s %d %ld",
 				"complicated_tag", 
-				(int)tag.opt.pair.primary, 
-				(long int)tag.opt.pair.secondary);
+				(int) tag.opt.pair.primary, 
+				(long int) tag.opt.pair.secondary);
 			break;
 		case MB_TAG_COMPLICATED_CONSTANT:
 			snprintf(buffer, buffer_len,
 				"%s %d %ld",
 				"complicated_constant_tag", 
-				(int)tag.opt.pair.primary, 
-				(long int)tag.opt.pair.secondary);
+				(int) tag.opt.pair.primary, 
+				(long int) tag.opt.pair.secondary);
 			break;
 		case MB_TAG_ENUM:
 			snprintf(buffer, buffer_len,
 				"%s %d",
 				"enum_tag",
-				(int)tag.opt.enum_tag);
+				(int) tag.opt.enum_tag);
 			break;
 		case MB_TAG_NONE:
 			snprintf(buffer, buffer_len,
@@ -794,7 +806,7 @@
 			break;
 		default:
 			MB_util_error("Invalid tag: %d\n", tag.id);
-			assert(FALSE); /*XXX*/
+			assert(FALSE); /* XXX */
 			break;
 	} /* end switch */
 	
@@ -803,9 +815,9 @@
 } /* end print_tag() */
 
 /*
-**	XXX: Currently we depend on the order of elements in the table.
+** XXX ORDER: Currently we depend on the order of elements in the table.
 */
-static const char*
+static const char *
 bytecode_table[] = {
 	"enter_pred",
 	"endof_pred",
@@ -851,20 +863,20 @@
 	"endof_negation_goal"
 };
 
-static const MB_CString
+static MB_CString_Const
 str_bytecode_name(MB_Byte bytecode_id)
 {
 	if (bytecode_id >= sizeof(bytecode_table) / sizeof(*bytecode_table)) {
-		return (const MB_CString)"<<unknown bytecode>>"; /*XXX*/
+		return (MB_CString_Const) "<<unknown bytecode>>"; /* XXX */
 	} else {
-		return (const MB_CString)bytecode_table[bytecode_id];
+		return (MB_CString_Const) bytecode_table[bytecode_id];
 	}
 }
 
 /*
-**	XXX: Currently we depend on the order of elements in the table.
+** XXX ORDER: Currently we depend on the order of elements in the table.
 */
-static const char*
+static const char *
 determinism_table[] = {
 	"det",
 	"semidet",
@@ -877,23 +889,23 @@
 };
 
 /* Returns a string corresponding to the name of a determinism type */
-static const MB_CString
+static MB_CString_Const
 str_determinism_name(MB_Byte determinism_id)
 {
 	if (determinism_id >=
 		sizeof(determinism_table) / sizeof(*determinism_table))
 	{
-		return (const MB_CString)"<<unknown determinism>>"; /*XXX*/
+		return (MB_CString_Const) "<<unknown determinism>>"; /* XXX */
 	} else {
-		return (const MB_CString)determinism_table[determinism_id];
+		return (MB_CString_Const) determinism_table[determinism_id];
 	}
 }
 
 
 /*
-**	XXX: Currently we depend on the order of elements in the table.
+** XXX ORDER: Currently we depend on the order of elements in the table.
 */
-static const char*
+static const char *
 unop_table[] = {
 	"mktag",
 	"tag",
@@ -907,22 +919,22 @@
 };
 
 /* Return a string corresponding to the name of a unary operation */
-static const MB_CString
+static MB_CString_Const
 str_unop_name(MB_Byte unop)
 {
 	/* bounds check */
 	
 	if (unop >= sizeof(unop_table) / sizeof(*unop_table)) {
-		return (const MB_CString)"<<unknown unop>>";	/* XXX */
+		return (MB_CString_Const) "<<unknown unop>>";	/* XXX */
 	} else {
-		return (const MB_CString)unop_table[unop];
+		return (MB_CString_Const) unop_table[unop];
 	}
 }
 
 /*
-**	XXX: Currently we depend on the order of elements in the table.
+** XXX ORDER: Currently we depend on the order of elements in the table.
 */
-static const char*
+static const char *
 binop_table[] = {
 	"+",
 	"-",
@@ -962,14 +974,14 @@
 	"body"
 };
 
-static const MB_CString
+static MB_CString_Const
 str_binop_name(MB_Byte binop)
 {
 	/* bounds check */
 	if (binop >= sizeof(binop_table) / sizeof(*binop_table)) {
-		return (const MB_CString)"<<unknown binop>>"; /*XXX*/
+		return (MB_CString_Const) "<<unknown binop>>"; /* XXX */
 	} else {
-		return (const MB_CString)binop_table[binop];
+		return (MB_CString_Const) binop_table[binop];
 	}
 } /* end str_binop_name() */
 
@@ -977,7 +989,7 @@
 /* Fills a buffer with a string transformed into a source-style c string 
  * (includes double quotes around string) */
 static void
-quote_cstring(MB_CString str, char* buffer, int buffer_len)
+quote_cstring(MB_CString str, char * buffer, int buffer_len)
 {
 	int		i;	/* index into str */
 	int		j;	/* index into buffer */
@@ -1026,64 +1038,74 @@
 } /* end quote_cstring() */
 
 static void
-str_var_dir(MB_Var_dir var_dir, char* buffer, int buffer_len)
+str_var_dir(MB_Var_dir var_dir, char *buffer, int buffer_len)
 {
-	Print()
+	PRINT()
 		"<<var_dir>>"
-	EndPrint()
+	ENDPRINT()
 	return;
 } /* end str_var_dir() */
 
 static void
-str_op_arg(MB_Op_arg op_arg, char* buffer, int buffer_len)
+str_op_arg(MB_Op_arg op_arg, char *buffer, int buffer_len)
 {
 	switch (op_arg.id) {
 		case MB_ARG_VAR:
-			Print()
+			PRINT()
 				"[var %d]",
 				op_arg.opt.var
-			EndPrint()
+			ENDPRINT()
 			break;
 		case MB_ARG_INT_CONST:
-			Print()
-				"[int %x]",
-				(int) op_arg.opt.int_const
-			EndPrint()
+			PRINT()
+				/*
+				** XXX: int_const has type Integer which could
+				** be int, long or long long. Correct solution
+				** is to define a format string in conf.h, but
+				** for now assume long is enough
+				*/
+				"[int " MB_FMT_INT " (" MB_FMT_HEX ")]",
+				op_arg.opt.int_const,
+				op_arg.opt.int_const
+			ENDPRINT()
 			break;
 		case MB_ARG_FLOAT_CONST:
-			Print()
+			PRINT()
 				"[float %f]",
 				op_arg.opt.float_const
-			EndPrint()
+			ENDPRINT()
 			break;
 		default:
-			assert(FALSE); /*XXX*/
+			assert(FALSE); /* XXX */
 			break;
 	} /* end switch */
 } /* end str_op_arg() */
 
-/* displays a code listing from address start to end
+/*
+** displays a code listing from address start to end
 */
 
 void
-MB_listing(MB_Machine_State* ms, FILE* fp, MB_Word* start, MB_Word* end,
+MB_listing(MB_Machine_State *ms, FILE *fp, MB_Bytecode_Addr start,
MB_Bytecode_Addr end,
 	MB_Word line_len)
 {
 	char buffer[256];
-	MB_Word* i;
+	MB_Bytecode_Addr i;
 	MB_Word	indent = 0;
-	MB_Word* ip = MB_ip_get(ms);
+	MB_Bytecode_Addr ip = MB_ip_get(ms);
 
-	SAY("linelen: %d\n", line_len);
+	MB_SAY("linelen: %d\n", line_len);
 
-	start = MB_code_range_check(start);
-	end = MB_code_range_check(end);
+	start = MB_code_range_clamp(start);
+	end = MB_code_range_clamp(end);
 
 	if (sizeof(buffer) < line_len) line_len = sizeof(buffer);
 
-	/* backtrack to the previous predicate */
-	/* and assume that it is at indent level 0 */
-	i = MB_code_get_pred_adr(start);
+	/*
+	** backtrack to the previous predicate 
+	** and assume that it is at indent level 0
+	*/
+	i = MB_code_get_pred_addr(start);
 
 	if (i != MB_CODE_INVALID_ADR) {
 		/* work out the indent level at the start */
--- ../bytecode.posted/mb_interface.h	Tue Jan 30 14:04:54 2001
+++ mb_interface.h	Tue Jan 30 16:21:22 2001
@@ -1,3 +1,4 @@
+
 /*
 ** Copyright (C) 2000-2001 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
@@ -11,42 +12,48 @@
 #define	MB_INTERFACE_H
 
 #include "mb_basetypes.h"
+#include "mb_module.h"
 #include "mb_util.h"
 
 typedef struct {
-	/*
-	** if cached_adr is NULL, this function hasn't been looked up yet
-	*/
-
-	MB_Word*	cached_ip;
-	const char*	module_name;
-	const char*	pred_name;
+	/* if cached_ip is NULL, this procedure hasn't been looked up yet */
+	MB_Bytecode_Addr cached_ip;
+
+	const char	*module_name;
+	const char	*pred_name;
 	MB_Word		proc_num;
 	MB_Word		arity;
-	MB_Byte		is_func;
+	MB_Bool		is_func;
 } MB_Call;
 
-/* Entry point for a native code call to det bytecode */
-MB_Word*	MB_bytecode_call_entry(MB_Call* bytecode_call);
+/*
+** Entry point for a native code call to det bytecode.
+** Returns native code address to return to
+*/
+MB_Native_Addr		MB_bytecode_call_entry(MB_Call *bytecode_call);
 
-/* Return to deterministic code after call to native code */
-MB_Word*	MB_bytecode_return_det(void);
+/*
+** Return to deterministic code after call to native code.
+** Returns native code address to return to.
+** Determines bytecode address to jump to by the contents of the
+** MB_DETFRAME_BC_SUCCIP det stack slot
+*/
+MB_Native_Addr		MB_bytecode_return_det(void);
 
 /* Returns pointer to the stub that calls bytecode_return_det */
-MB_Word*	MB_native_get_return_det(void);
+MB_Native_Addr		MB_native_get_return_det(void);
 
 /* Find the native code entry point for a procedure */
-MB_Word*	MB_code_find_proc_native(MB_CString_Const module,
+MB_Native_Addr		MB_code_find_proc_native(MB_CString_Const module,
 			MB_CString_Const pred, MB_Word proc,
-			MB_Word arity, MB_Byte is_func);
+			MB_Word arity, MB_Bool is_func);
 
 /**************************************************************/
 /*
 ** det stack
 ** 
-** Each det stack frame looks like the following:
-**  sp-0:   [succip]
-**  sp-1:   [semidet success indicator - may or may not be there]
+** Each normal det stack frame looks like the following:
+**  sp-1:   [succip]
 **  sp-2:   [var 0]
 **  sp-3:   [var 1]
 **            ...
@@ -54,17 +61,41 @@
 **  sp-n-1: [temp 1]
 **            ...
 **
-** Note the addition of [number of vars] so that MB_func_type_check
-** can determine where the temp list begins
+** If model semidet, then temp 0 is the semidet success indicator
 */
 
-#define MB_DETFRAME_SUCCIP	(0)	/* saved succip */
-#define MB_DETFRAME_BC_SUCCIP	(1)	/* bytecode return address for stub */
+/* saved succip */
+#define MB_DETFRAME_SUCCIP			(1)
 
-#define MB_DETFRAME_SIZE 	(2)	/* size of det stack frame */
+/* fixed size of deterministic stack frame */
+#define MB_DETFRAME_SIZE			(1)
 
 /*
-** nondet stack
+**
+** An interface det stack frame is pushed when bytecode wishes
+** to jump to native code and later return to bytecode. succip
+** will have been set to a stub that reads the interface stack
+** frame and directs control appropriately
+**  sp-1:   [succip in bytecode to return to] 
+**  sp-2:   [initial frame]
+**
+** The initial frame field is used to determine whether a procedure should
+** return to bytecode or native code when it reaches endof_proc. If it reaches
+** an endof_proc instruction and after removing its stack frame finds that the
+** (det or nondet) stack pointer is equal to the initial frame it knows that
+** it is the most ancestral called procedure and should return to native code
+** 
+*/
+
+/* bytecode return address for stub */
+#define MB_DETFRAME_INTERFACE_BC_SUCCIP		(1)
+#define MB_DETFRAME_INTERFACE_INITIAL_FRAME	(2)
+
+/* Size of a deterministic interface frame */
+#define MB_DETFRAME_INTERFACE_SIZE		(2)
+
+/*
+** Nondet stack
 **
 ** An ordinary stack frame looks like so:
 ** curfr[ 0]	prevfr
@@ -85,12 +116,17 @@
 #define MB_FRAME_SUCCIP		(3)
 #define MB_FRAME_SUCCFR		(4)
 
+/* size of normal nondet stack frame */
 #define MB_FRAME_SIZE		5
+
+/* size of temp nondet stack frame created by model det/semidet code */
 #define MB_FRAME_TEMP_DET_SIZE	4
+
+/* size of temp nondet stack frame created by model nondet code */
 #define MB_FRAME_TEMP_SIZE	3
 
 /* Invalid frame address */
-#define MB_FRAME_INVALID	((MB_Word)(-1))
+#define MB_FRAME_INVALID	((MB_Word) (-1))
 
 /*
 ** semidet success flags: stored in a temp slot until the procedure
@@ -110,15 +146,15 @@
 #define MB_curfr	MR_virtual_curfr
 #define MB_maxfr	MR_virtual_maxfr
 
-/* Det stack: 0 is the top (unused), 1 is the first used slot*/
+/* Det stack: 1 is the top (used - slot 0 is unused) */
 #define MB_stackitem(x)	((MB_sp)[-(x)])
 
-/* Nondet stack - same as with det statck*/
+/* Nondet stack - same as with det statck */
 #define MB_frameitem(x)	((MB_maxfr)[-(x)])
 
-#define MB_incr_sp(x)	(					\
-			MB_sp = MB_sp + (x),	\
-			(void)0					\
+#define MB_incr_sp(x)	(		\
+			MB_sp += (x),	\
+			(void)0		\
 			)
 
 #define MB_decr_sp(x)	MB_incr_sp(-(x))
@@ -135,4 +171,3 @@
 
 
 #endif	/* MB_INTERFACE_H */
-
--- ../bytecode.posted/mb_interface.c	Tue Jan 30 14:04:54 2001
+++ mb_interface.c	Tue Jan 30 17:04:16 2001
@@ -1,3 +1,4 @@
+
 /*
 ** Copyright (C) 2000-2001 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
@@ -21,101 +22,25 @@
 
 /* Implementation */
 
-/*
-** A native code procedure wishes to call a deterministic bytecode procedure
-*/
-
-#include "mb_machine_def.h"	/* needed to instantiate MB_Machine_State */
-
-/* This is called when native code wishes to call bytecode */
-MB_Word*
-MB_bytecode_call_entry(MB_Call* bytecode_call)
-{
-
-	MB_Word* ip;
-
-	SAY("\n\nHello from bytecode_entry_det");
-	if ((void*)bytecode_call->cached_ip == NULL) {
-		SAY("mad cow");
-		ip = MB_code_find_proc(bytecode_call->module_name,
-			bytecode_call->pred_name,
-			bytecode_call->proc_num,
-			bytecode_call->arity,
-			bytecode_call->is_func);
-	} else {
-		SAY("fast mad cow");
-		ip = bytecode_call->cached_ip;
-	}
-	if (ip == MB_CODE_INVALID_ADR) {
-		MB_util_error("Attempting to call bytecode %s %s__%s/%d (%d):",
-			bytecode_call->is_func ? "func" : "pred",
-			bytecode_call->module_name,
-			bytecode_call->pred_name,
-			bytecode_call->arity,
-			bytecode_call->proc_num);
-		MB_fatal("Unable to find procedure\n"
-			"(Is the native code and bytecode consistent?)");
-	}
-
-	SAY(" bytecode adr %04x", ip);
+MR_declare_entry(MB_native_return_det_stub);
 
-	{
-		/* Create a new machine and start executing */
-		MB_Machine_State ms;
-		MB_machine_create(ip, &ms);
-		ip = MB_machine_exec(&ms);
-	}
-	
-	return ip;
-}
-
-/*
-** When a det procedure wishes to call native code:
-** Bytecode sets SUCCIP to MB_bytecode_return_det,
-** Bytecode sets MB_DETFRAME_BC_SUCCIP to bytecode return address
-** returns to native code, passing the address of the native code
-**  to be called
-**
-** After native code is finished, returns to this function which
-** reads MB_DETFRAME_BC_SUCCIP and returns to that location
-*/
-MB_Word*
-MB_bytecode_return_det(void)
-{
-	MB_Word* ip = (MB_Word*)MB_stackitem(MB_DETFRAME_BC_SUCCIP);
-
-	MB_Machine_State ms;
-	MB_machine_create(ip, &ms);
-
-	ip = MB_machine_exec(&ms);
-
-	return ip;
-}
-
-MB_Word*
+MB_Native_Addr
 MB_native_get_return_det(void)
 {
-	static MB_Word* return_det_stub = NULL;
-	if (return_det_stub == NULL) {
-		return_det_stub =
-			MB_code_find_proc_native(
-				"mb_interface_stub",
-				"mb_native_return_det",
-				0, 1, FALSE);
-	}
-	return return_det_stub;
+	return (MB_Native_Addr) MR_ENTRY(MB_native_return_det_stub);
 }
 
 
-MB_Word*
+/* Search for the native code address of a procedure */
+MB_Native_Addr
 MB_code_find_proc_native(MB_CString_Const module, MB_CString_Const pred,
-			MB_Word proc, MB_Word arity, MB_Byte is_func)
+			MB_Word proc, MB_Word arity, MB_Bool is_func)
 {
 	MR_Matches_Info matches;
 	MR_Proc_Spec spec;
 
 	MR_register_all_modules_and_procs(stderr, TRUE);
-	SAY("\n");
+	MB_SAY("\n");
 
 	spec.MR_proc_module = module;
 	spec.MR_proc_name = pred;
@@ -123,13 +48,13 @@
 	spec.MR_proc_mode = proc;
 	spec.MR_proc_pf = (is_func) ? MR_FUNCTION : MR_PREDICATE;
 
-	SAY("Looking for procedures .... ");
+	MB_SAY("Looking for procedures .... ");
 	matches = MR_search_for_matching_procedures(&spec);
 
 	{
 		MB_Word i;
 		for (i = 0; i < matches.match_proc_next; i++) {
-			SAY("Match %d: %s %s__%s/%d (%d)",
+			MB_SAY("Match %d: %s %s__%s/%d (%d)",
 				i,
 				(matches.match_procs[i]
 					->MR_sle_proc_id.MR_proc_user
@@ -156,12 +81,12 @@
 			return NULL;
 		case 1:
 			{
-				MB_Word adr = (MB_Word)
+				MB_Native_Addr addr = (MB_Native_Addr)
 				matches.match_procs[0]->
 					MR_sle_traversal.MR_trav_code_addr;
-				SAY("Adr %08x", adr);
+				MB_SAY("Adr %08x", addr);
 			}
-			return matches.match_procs[0]->
+			return (MB_Native_Addr)matches.match_procs[0]->
 				MR_sle_traversal.MR_trav_code_addr;
 		default:
 			MB_fatal("More than one native code entry found!");
@@ -169,4 +94,96 @@
 	}
 }
 
+/*
+** A native code procedure wishes to call a deterministic bytecode procedure
+*/
+
+/*
+** Needed to instantiate MB_Machine_State. Not #included above because nothing
+** else in this module should need to know what is inside an MB_Machine_State
+*/
+#include "mb_machine_def.h"	
+
+MB_Native_Addr
+MB_bytecode_call_entry(MB_Call *bytecode_call)
+{
+
+	MB_Native_Addr		native_ip;
+	MB_Bytecode_Addr	bc_ip;
+	MB_SAY("Det stack is at %08x", MB_sp);
+
+	MB_SAY("\n\nHello from bytecode_entry_det");
+
+	if ((void *) bytecode_call->cached_ip == NULL) {
+		bc_ip = MB_code_find_proc(bytecode_call->module_name,
+			bytecode_call->pred_name,
+			bytecode_call->proc_num,
+			bytecode_call->arity,
+			bytecode_call->is_func);
+	} else {
+		bc_ip = bytecode_call->cached_ip;
+	}
+	if (bc_ip == MB_CODE_INVALID_ADR) {
+		MB_util_error("Attempting to call bytecode %s %s__%s/%d (%d):",
+			bytecode_call->is_func ? "func" : "pred",
+			bytecode_call->module_name,
+			bytecode_call->pred_name,
+			bytecode_call->arity,
+			bytecode_call->proc_num);
+		MB_fatal("Unable to find procedure\n"
+			"(Is the native code and the bytecode consistent?)");
+	}
+
+	MB_SAY(" bytecode addr %08x", bc_ip);
+
+	{
+		/* Create a new machine and start executing */
+		MB_Machine_State ms;
+		MB_machine_create(&ms, bc_ip, NULL);
+
+		MB_SAY("ZZZ ENTERING BYTECODE");
+		MB_show_state(&ms, stderr);
+
+		native_ip = MB_machine_exec(&ms);
+
+		MB_SAY("ZZZ RETURNING TO NATIVE1");
+		MB_show_state(&ms, stderr);
+	}
+	
+	return native_ip;
+}
+
+/*
+** This is the reentry point after a det bytecode procedure has called
+** native code. See mb_interface.h for a description of how this occurs
+*/
+MB_Native_Addr
+MB_bytecode_return_det(void)
+{
+	/* Get the bytecode reentry address */
+	MB_Bytecode_Addr ip = (MB_Bytecode_Addr)
+		MB_stackitem(MB_DETFRAME_INTERFACE_BC_SUCCIP);
+	/* Get the initial stack frame */
+	MB_Word *initial_frame = (MB_Word *)
+		MB_stackitem(MB_DETFRAME_INTERFACE_INITIAL_FRAME);
+
+	MB_Native_Addr ret_ip;
+
+	MB_Machine_State ms;
+
+	MB_decr_sp(MB_DETFRAME_INTERFACE_SIZE);
+
+	MB_machine_create(&ms, ip, initial_frame);
+
+	MB_SAY("ZZZ RETURNING TO BYTECODE");
+	MB_show_state(&ms, stderr);
+
+	ret_ip = MB_machine_exec(&ms);
+
+	MB_SAY("ZZZ RETURNING TO NATIVE2");
+	MB_show_state(&ms, stderr);
+
+	return ret_ip;
+
+}
 
--- ../bytecode.posted/mb_machine_show.h	Tue Jan 30 14:04:54 2001
+++ mb_machine_show.h	Thu Jan 25 16:20:53 2001
@@ -16,10 +16,10 @@
 #include "mb_machine.h"
 
 /* Display the current state of the machine */
-void MB_show_state(MB_Machine_State* ms, FILE* fp);
+void MB_show_state(MB_Machine_State *ms, FILE *fp);
 
 /* Display the call stack of the machine */
-void MB_show_call(MB_Machine_State* ms, FILE* fp);
+void MB_show_call(MB_Machine_State *ms, FILE *fp);
 
 #endif	/* MB_MACHINE_SHOW_H */
 
--- ../bytecode.posted/mb_machine_show.c	Tue Jan 30 14:04:54 2001
+++ mb_machine_show.c	Tue Jan 30 17:00:43 2001
@@ -6,7 +6,7 @@
 **
 */
 
-#include	<mercury_imp.h>
+#include	"mercury_imp.h"
 
 /* Imports */
 #include	<stdio.h>
@@ -21,78 +21,106 @@
 
 /* Exported definitions */
 
-void		MB_show_state(MB_Machine_State* ms, FILE* fp);
+void		MB_show_state(MB_Machine_State *ms, FILE *fp);
 
 /* Local declarations */
 
 #define NREGS	14
 #define NSTACK	8
 
+
 /* Display the current state of the machine */
+#define LINE_LEN	78	/* XXX: make this adjustable */
 void
-MB_show_state(MB_Machine_State* ms, FILE* fp)
+MB_show_state(MB_Machine_State *ms, FILE *fp)
 {
-	char buffer[78];
-	MB_Word* ip = MB_ip_get(ms);
+	char buffer[LINE_LEN];
+	MB_Bytecode_Addr ip = MB_ip_get(ms);
 
 	/* Work out what predicate & proc we are in */
-	MB_Word* cur_pred = MB_code_get_pred_adr(ip);
-	MB_Word* cur_proc = MB_code_get_proc_adr(ip);
+	MB_Bytecode_Addr cur_pred;
+	MB_Bytecode_Addr cur_proc;
 
 	if (fp == NULL) return;
 
 	fprintf(fp, "----------------------------------------"
 			"------------------------------------\n");
-	if (MB_code_range_check(ip) != ip) {
-		fprintf(fp, "   Invalid execution address\n");
-		return;
-	}
 
-	/* Show what predicate we are in */
-	MB_str_bytecode(ms, cur_pred, buffer, sizeof(buffer), 0);
-	fprintf(fp, "%s\n", buffer);
+	if (MB_code_range_clamp(ip) == ip) {
+		/* Show what predicate we are in */
+		cur_pred = MB_code_get_pred_addr(ip);
+		cur_proc = MB_code_get_proc_addr(ip);
 
-	MB_str_bytecode(ms, cur_proc, buffer, sizeof(buffer), 1);
-	fprintf(fp, "%s\n", buffer);
+		MB_str_bytecode(ms, cur_pred, buffer, sizeof(buffer), 0);
+		fprintf(fp, "%s\n", buffer);
 
-	fprintf(fp, "\n");
+		MB_str_bytecode(ms, cur_proc, buffer, sizeof(buffer), 1);
+		fprintf(fp, "%s\n", buffer);
+
+		fprintf(fp, "\n");
 
-	/* show the surrounding lines of code */
-	MB_listing(ms, fp, ip-2, ip+4, 73);
+		fprintf(fp, "ip: %p\n", ip);
+
+		/* show the surrounding lines of code */
+		MB_listing(ms, fp, ip - 2, ip + 4, LINE_LEN);
+	} else {
+		if (MB_ip_special(ip)) {
+			fprintf(fp, " Special execution address (%p)\n", ip);
+		} else {
+			fprintf(fp, "   Invalid execution address\n");
+		}
+	}
 
 	fprintf(fp, "\n");
 
 	{
-		MB_Word i;
+		int i;
 
 		/* Show the registers */
 		for (i = 0; i < NREGS; i++) {
-			fprintf(fp, "reg[%02d] = %08x      ",
-					(int)i, (int)MB_reg(i));
+			int j = i / 2 +
+				((i & 1) ? (NREGS / 2) : 0);
+			fprintf(fp, "reg[%02d] = " MB_FMT_INT" ("MB_FMT_HEX ")       ",
+					j, MB_reg(j), MB_reg(j));
 			if (i & 1) {
 				fprintf(fp, "\n");
 			}
 		}
-		if (i & 1) {
+		if (!(i & 1)) {
 			fprintf(fp, "\n");
 		}
 
+		fprintf(fp, "\n");
+		
+		/* Show the machine state */
+		fprintf(fp,	" succip     = " MB_FMT_HEX "                "
+				" 0          = " MB_FMT_HEX "\n",
+				(MB_Unsigned) MB_succip,
+				(MB_Unsigned) 0);
+
+		fprintf(fp,	" init_frame = " MB_FMT_HEX "                "
+				" natv_retun = " MB_FMT_HEX "\n",
+				(MB_Unsigned) ms->initial_stack,
+				(MB_Unsigned) ms->native_return);
+
 		/* Show the stack */
 		fprintf(fp, "\n");
 
-		fprintf(fp,	" sp         = %08x  "
-				" maxfr      = %08x\n",
-				(int)MB_sp,
-				(int)MB_maxfr);
-		for (i = 0; i < NSTACK; i++) {
-			fprintf(fp,	"%cdet[%02d]    = %08x  "
-					"%cnondet[%02d] = %08x\n",
+		fprintf(fp,	" sp         = " MB_FMT_HEX "                "
+				" maxfr      = " MB_FMT_HEX "\n",
+				(MB_Unsigned) MB_sp,
+				(MB_Unsigned) MB_maxfr);
+		for (i = 1; i < NSTACK; i++) {
+			fprintf(fp,	"%cdet[%02d]    = " MB_FMT_INT
+						" (" MB_FMT_HEX ")  "
+					"%cnondet[%02d] = " MB_FMT_INT
+						" (" MB_FMT_HEX ")\n",
 				(&MB_stackitem(i) == ms->cur_proc.var) ?
 					'>' : ' ',
-				(int)i, MB_stackitem(i),
+				(int) i, MB_stackitem(i), MB_stackitem(i),
 				(&MB_frameitem(i) == ms->cur_proc.var) ?
 					'>' : ' ',
-				(int)i, MB_frameitem(i));
+				(int) i, MB_frameitem(i), MB_frameitem(i));
 		}
 	}
 
--- ../bytecode.posted/mb_mem.h	Tue Jan 30 14:04:54 2001
+++ mb_mem.h	Mon Jan 29 18:16:42 2001
@@ -1,11 +1,9 @@
 
 /*
-** Copyright (C) 1997-2001 The University of Melbourne.
+** Copyright (C) 1997,2000-2001 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
 ** Public License - see the file COPYING.LIB in the Mercury distribution.
 **
-** $$
-**
 ** This file provides basic memory management interfaces
 ** 
 */
@@ -18,14 +16,9 @@
 #include "mb_basetypes.h"
 
 /*
-** Initialise memory allocation
-*/
-void MB_mem_init(void);
-
-/*
 ** Do not use MB_malloc() or MB_realloc() directly, unless you want
 ** to allocate raw memory.  Normally you should use the macros
-** MB_new(), MB_new_array(), and MB_resize_array() instead.
+** MB_NEW(), MB_NEW_ARRAY(), and MB_RESIZE_ARRAY() instead.
 **
 ** None of these are garbage collected and are invisible to the garbage
 ** collector
@@ -42,14 +35,14 @@
 
 void MB_free(void *mem);
 
-#define MB_new(type)		((type *) MB_malloc(sizeof(type)))
-#define MB_new_array(type, num)	((type *) MB_malloc((num) * sizeof(type)))
-#define MB_resize_array(array, type, num) \
+#define MB_NEW(type)		((type *) MB_malloc(sizeof(type)))
+#define MB_NEW_ARRAY(type, num)	((type *) MB_malloc((num) * sizeof(type)))
+#define MB_RESIZE_ARRAY(array, type, num) \
 	((type *) MB_realloc((array), (num) * sizeof(type)))
 
 /*
 ** Garbage collected versions of the above
-**
+** Uses Hans Boehm's conservative garbage collector
 */
 
 /* Atomic == doesn't contain any pointers */
@@ -58,23 +51,25 @@
 
 void* MB_GC_malloc_atomic(size_t size);
 
+/* works for both atomic and nonatomic memory */
 void* MB_GC_realloc(void* mem, size_t size);
 
 void MB_GC_free(void *mem);
 
-#define MB_GC_new(type) \
+#define MB_GC_NEW(type) \
 	((type *) MB_GC_malloc(sizeof(type)))
 
-#define MB_GC_new_atomic(type) \
+#define MB_GC_NEW_ATOMIC(type) \
 	((type *) MB_GC_malloc_atomic(sizeof(type)))
 	
-#define MB_GC_new_array(type, num) \
+#define MB_GC_NEW_ARRAY(type, num) \
 	((type *) MB_GC_malloc((num) * sizeof(type)))
 	
-#define MB_GC_new_array_atomic(type, num) \
+#define MB_GC_NEW_ARRAY_ATOMIC(type, num) \
 	((type *) MB_GC_malloc((num) * sizeof(type)))
 
-#define MB_GC_resize_array(array, type, num) \
+/* works for both atomic and nonatomic memory */
+#define MB_GC_RESIZE_ARRAY(array, type, num) \
 	((type *) MB_GC_realloc((array), (num) * sizeof(type)))
 
 #endif	/* MB_MEM_H */
--- ../bytecode.posted/mb_mem.c	Tue Jan 30 14:04:54 2001
+++ mb_mem.c	Tue Jan 30 11:48:42 2001
@@ -1,6 +1,6 @@
 
 /*
-** Copyright (C) 1997-2001 The University of Melbourne.
+** Copyright (C) 1997,2000-2001 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
 ** Public License - see the file COPYING.LIB in the Mercury distribution.
 **
@@ -9,7 +9,7 @@
 /* Imports */
 #include	<stdlib.h>
 #include	<string.h>
-#include	<mercury_tags.h>
+#include	"mercury_tags.h"
 
 #include	"mb_mem.h"
 #include	"mb_util.h"
@@ -30,33 +30,12 @@
 /* Implementation */
 
 #ifndef MB_NO_GC
-# pragma message "Garbage collection is on"
-# define GC_DEBUG
-# include <gc.h>
-#else
-# pragma message "Garbage collection is off"
-#endif
 
+#include "gc.h"
 
-/*
-** Initialise memory allocation
-*/
-void
-MB_mem_init()
-{
-#ifndef MB_NO_GC
-	int i;
-	
-	/* Initialise the garbage collector */
-	GC_INIT();
-
-	for (i = 0; i < (1 << TAGBITS); i++) {
-		GC_REGISTER_DISPLACEMENT(i);
-	}
 #endif
-}
 
-void*
+void *
 MB_malloc(size_t size)
 {
 	size_t		real_size;
@@ -105,10 +84,12 @@
 	return;
 }
 
-void*
+void *
 MB_realloc(void *mem, size_t size)
 {
 
+	return realloc(mem, size);
+#if 0
 	void	*new_mem;
 
 	/*
@@ -126,19 +107,20 @@
 	MB_free(mem);
 
 	return new_mem;
+#endif
 }
 
 /* ------------------------------------------------------------------------- */
 
 #ifndef MB_NO_GC
 
-void*
+void *
 MB_GC_malloc(size_t size)
 {
 	return GC_malloc(size);
 }
 
-void*
+void *
 MB_GC_malloc_atomic(size_t size)
 {
 	return GC_malloc_atomic(size);
@@ -150,7 +132,7 @@
 	GC_free(mem);
 }
 
-void*
+void *
 MB_GC_realloc(void *mem, size_t size)
 {
 	return GC_realloc(mem, size);
@@ -158,7 +140,7 @@
 
 #else	/* MB_NO_GC */
 
-void*
+void *
 MB_GC_malloc(size_t size, MB_Bool atomic)
 {
 	return MB_malloc(size);
@@ -167,10 +149,10 @@
 void
 MB_GC_free(void *mem)
 {
-	return MB_free(mem);
+	MB_free(mem);
 }
 
-void*
+void *
 MB_GC_realloc(void *mem, size_t size)
 {
 	return MB_realloc(mem, size);
--- ../bytecode.posted/mb_module.h	Tue Jan 30 14:04:54 2001
+++ mb_module.h	Tue Jan 30 16:54:00 2001
@@ -1,3 +1,4 @@
+
 /*
 ** Copyright (C) 2000-2001 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
@@ -15,8 +16,8 @@
 #include "mb_bytecode.h"
 #include "mb_util.h"
 
-struct MB_Module_Tag;
-typedef struct MB_Module_Tag	MB_Module;
+struct MB_Module_Struct;
+typedef struct MB_Module_Struct	MB_Module;
 
 /*
 ** Special code addresses. INVALID_ADR must be last as the asserts
@@ -24,65 +25,77 @@
 **
 ** If you alter these, ensure MB_ip_special reflects this
 */
-#define MB_CODE_DO_FAIL		((MB_Word*)(-1))
-#define MB_CODE_DO_REDO		((MB_Word*)(-2))
-#define MB_CODE_NATIVE_RETURN	((MB_Word*)(-3))
-#define MB_CODE_INVALID_ADR	((MB_Word*)(-4))
+#define MB_CODE_DO_FAIL		((MB_Bytecode_Addr) (-1))
+#define MB_CODE_DO_REDO		((MB_Bytecode_Addr) (-2))
+#define MB_CODE_NATIVE_RETURN	((MB_Bytecode_Addr) (-3))
+#define MB_CODE_INVALID_ADR	((MB_Bytecode_Addr) (-4))
+
+/* Ensure a module is loaded */
+MB_Module	*MB_module_load_name(MB_CString_Const module_name);
+MB_Module	*MB_module_load(MB_CString_Const module_name, FILE *fp);
+/* Unload a module */
+void		MB_module_unload(MB_Module *module);
 
 /*
-** A native code procedure wishes to call a deterministic bytecode procedure
+** Returns a pointer to a given module.
+** If the module is not loaded, loads it.
 */
-MB_Module*	MB_module_load_name(MB_CString_Const module_name);
-MB_Module*	MB_module_load(MB_CString_Const module_name, FILE* fp);
-void		MB_module_unload(MB_Module* module);
+MB_Module	*MB_module_get(MB_CString_Const module_name);
 
-/*
-** returns a pointer to a given module
-** If the module is not loaded, loads it
-*/
-MB_Module*	MB_module_get(MB_CString_Const module_name);
+/* Return the number of bytecodes loaded so far */
+MB_Unsigned	MB_code_size(void);
+
+/* Return the bytecode id of the bytecode at a given address */
+MB_Byte		MB_code_get_id(MB_Bytecode_Addr addr);
+
+/* Get the procedure model that a bytecode at a given address is in */
+#define MB_ISDET_NO		0	/* nondet */
+#define MB_ISDET_YES		1	/* det, semidet */
+MB_Byte		MB_code_get_det(MB_Bytecode_Addr addr);
 
-/* Return the number  of bytecodes there are */
-MB_Word		MB_code_size(void);
-/* Read the bytecode at a given address */
-/*MB_Bytecode	MB_code_get(MB_Word*adr);*/
-/* Get the bytecode type at a given address */
-MB_Byte		MB_code_get_id(MB_Word*adr);
-
-#define MB_ISDET_NO		0
-#define MB_ISDET_YES		1
-/* Get the determinism of the procedure a code at a given address is in */
-MB_Byte		MB_code_get_det(MB_Word*adr);
 /* Get the bytecode argument at a given address */
-MB_Bytecode_Arg*MB_code_get_arg(MB_Word*adr);
+MB_Bytecode_Arg	*MB_code_get_arg(MB_Bytecode_Addr addr);
+
 /* Get the predicate in which the following address resides */
-/*MB_Bytecode	MB_code_get_pred(MB_Word* adr);*/
-MB_Word*	MB_code_get_pred_adr(MB_Word* adr);
+MB_Bytecode_Addr MB_code_get_pred_addr(MB_Bytecode_Addr addr);
+
 /* Get the procedure in which the following address resides */
-/*MB_Bytecode	MB_code_get_proc(MB_Word* adr);*/
-MB_Word*	MB_code_get_proc_adr(MB_Word* adr);
+MB_Bytecode_Addr MB_code_get_proc_addr(MB_Bytecode_Addr addr);
 
-MB_Word*	MB_code_find_proc(MB_CString_Const module,
+MB_Bytecode_Addr MB_code_find_proc(MB_CString_Const module,
 			MB_CString_Const pred,
 			MB_Word proc,
 			MB_Word arity,
-			MB_Byte is_func);
+			MB_Bool is_func);
+
 /* Returns a code address clipped into the valid code range */
-MB_Word* MB_code_range_check(MB_Word* adr);
+MB_Bytecode_Addr MB_code_range_clamp(MB_Bytecode_Addr addr);
+
 /* True if the code address is 'normal' (not invalid or one of MB_CODE_xxx) */
-MB_Bool		MB_ip_normal(MB_Word* ip);
+MB_Bool		MB_ip_normal(MB_Bytecode_Addr ip);
+
 /* True if the code address is one of MB_CODE_xxx */
-MB_Bool		MB_ip_special(MB_Word* ip);
+MB_Bool		MB_ip_special(MB_Bytecode_Addr ip);
+
 /* True if a native code address */
-MB_Bool		MB_ip_native(MB_Word* ip);
+MB_Bool		MB_ip_native(MB_Bytecode_Addr ip);
 	
 /* Allocate memory in the code argument data array */
-#define MB_code_data_alloc(type, number) \
-	((type*)(MB_code_data_alloc_words(((sizeof(type)*(number))+3) / 4)))
+#define MB_CODE_DATA_ALLOC(type, number) \
+	((type *) (MB_code_data_alloc_words(MB_NUMBLOCKS(sizeof(type)*(number),
sizeof(MB_Word)))))
 
-MB_Word* MB_code_data_alloc_words(MB_Word num_words);
+MB_Word		*MB_code_data_alloc_words(MB_Word num_words);
 
+/*
+** This is only here so pointer arithmetic will work; you shold never need
+** to use any of these fields: the MB_BCID_xxx wrappers in mb_module.c are
+** the only things that should use them
+*/
+struct MB_BCId_Struct {
+	MB_Unsigned	id	: 7;
+	MB_Unsigned	is_det	: 1;
+	MB_Unsigned	arg	: MB_WORD_BITS - (7 + 1);
+};
 
 #endif	/* MB_MODULE_H */
-
--------------------------------------------------------------------------
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