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

Levi Cameron l.cameron2 at ugrad.unimelb.edu.au
Tue Jan 30 18:06:01 AEDT 2001


Full diff Part 1

Levi
 l.cameron2 at ugrad.unimelb.edu.au
---------------------------------------------
bytecode/bytecode.c:
bytecode/bytecode.h:
bytecode/dict.c:
bytecode/dict.h:
bytecode/disasm.c:
bytecode/disasm.h:
bytecode/machine.c:
bytecode/machine.h:
bytecode/mbi_main.c:
bytecode/mdb.m:
bytecode/mem.c:
bytecode/mem.h:
bytecode/slist.c:
bytecode/slist.h:
bytecode/template.c:
bytecode/template.h:
bytecode/util.c:
bytecode/util.h:
        Removed. These are all the old bytecode files from 
        before I started. Any parts that were useful have already 
        been salvaged and used in the new interpreter. 

bytecode/*:
	Added MB_Bytecode_Addr and MB_Native_Addr types to remove abiguity
	as to what type of code an instruction pointer points to, and
	provide compiler help for erroneously mixing pointer types.

bytecode/Mmakefile:
bytecode/Mmake.params:
        Makefile for test bytecode program. Note that any library 
        functions that are called from bytecode must be compiled 
        with trace information. (So their entry labels can be 
        looked up) 

bytecode/mb_basetypes.h:
        Added. Contains basic type definitions. 

bytecode/mb_bytecode.c:
bytecode/mb_bytecode.h:
        Better error messages. 
        Changed var_lists to direct pointers rather than 
        lookups through data stacks (much simpler but stop you 
        using realloc() on the bytecode argument data) 
        Label addresses are computed at module load time rather 
        than being looked up each jump 
        Added endof_negation_goal 
        Temporary stack slot numbers are translated to variable 
        numbers (now there is no distinction between temps & vars) 
        MB_read_cstring return value convention changed (see comments
	for how to now free the returned memory) 
        Added distinction between functions and predicates 
        Added enter_else 
        Code addresses are all pointers rather than simple ints
	Added MB_Code_Addr type for pred_const and call instructions

bytecode/mb_disasm.c:
bytecode/mb_disasm.h:
        Added endof_negation_goal & enter_else 
        Output strings are now easier to read 
        MB_listing does not display anything for invalid addresses 
        MB_listing takes line length argument 

bytecode/mb_interface.c:
bytecode/mb_interface.h:
bytecode/mb_interface_stub.m:
        Interfacing between native/bytecode 

bytecode/mb_machine.c:
bytecode/mb_machine.h:
bytecode/mb_machine_def.h:
        Large sections of code branched off into mb_module.? 
        Most instructions completed, but not integrated with native 
        code. 
        Most of mb_machine_def has been removed as the native 
        code functions provide the same functionality. 

bytecode/mb_machine_show.c:
bytecode/mb_machine_show.h:
        Completely changed. Less information now as a lot of what 
        was being displayed before cannot be determined as easily 
        now that it is stored in the mercury runtime. 

bytecode/mb_mem.c:
bytecode/mb_mem.h:
        Added routines for garbage collected memory 

bytecode/mb_module.c:
bytecode/mb_module.h:
        Loading & accessing bytecode. Argument data indexes & id are now 
        stored in a single word. (see MB_BCID_xxx macros). 
        Call & label addresses are now calculated at load time. 

bytecode/mb_stack.c:
bytecode/mb_stack.h:
        Added options for garbage collection of MB_Stack memory 

bytecode/mb_util.c:
bytecode/mb_util.h:
        Miscellaneous string functions added and SAY() for debugging 

bytecode/simple01.m:
        Added. Simple test program. (replace with whatever 
        program is being tested at the time). 

--- /dev/null	Wed Nov 22 17:39:10 2000
+++ mb_basetypes.h	Mon Jan 29 18:16:34 2001
@@ -0,0 +1,68 @@
+
+/*
+** Copyright (C) 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 contains the basic type definitions
+*/
+
+#ifndef MB_BASETYPES_H
+#define	MB_BASETYPES_H
+
+#include <stdio.h>
+
+#include "mercury_conf.h"
+#include "mercury_tags.h"
+#include "mercury_types.h"
+#include "mercury_float.h"
+
+typedef unsigned char
+	MB_Byte;
+
+typedef MR_INT_LEAST16_TYPE
+	MB_Short;
+
+typedef MR_Word
+	MB_Word;
+
+typedef MR_Unsigned
+	MB_Unsigned;
+
+#define MB_WORD_BITS	MR_WORDBITS
+
+typedef MR_Integer
+	MB_Integer;
+
+typedef MR_Float
+	MB_Float;
+
+typedef MR_Float64
+	MB_Float64;
+
+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.old/mb_bytecode.h	Wed Jan 24 18:42:22 2001
+++ mb_bytecode.h	Tue Jan 30 12:32:34 2001
@@ -1,18 +1,15 @@
 
 /*
-** Copyright (C) 1997 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.
 **
-** $Id: mb_bytecode.h,v 1.1 2001/01/24 07:42:22 lpcam Exp $
-**
 ** This file contains the bytecode format and data types
 ** This must be the same as that in compiler/bytecode.m
 */
 
-
 #ifndef MB_BYTECODE_H
-#define	MB_BYTECODE_H
+#define MB_BYTECODE_H
 
 #include <stdio.h>
 
@@ -20,31 +17,11 @@
 #include "mercury_types.h"
 #include "mercury_float.h"
 
+#include "mb_basetypes.h"
+#include "mb_stack.h"
 #include "mb_util.h"
 
-/* XXX expects sizeof(unsigned char) == 1 */
-typedef unsigned char
-	MB_Byte;
-
-typedef MR_INT_LEAST16_TYPE
-	MB_Short;
-
-typedef MR_Word
-	MB_Word;
-
-typedef MR_Integer
-	MB_Integer;
-
-typedef MR_Float
-	MB_Float;
-
-typedef MR_Float64
-	MB_Float64;
-
-typedef MR_Bool
-	MB_Bool;
-
-typedef struct MB_Tag_struct {
+typedef struct MB_Tag_Struct {
 	MB_Byte	id;
 	union {
 		MB_Byte	primary;
@@ -78,7 +55,29 @@
 #define	MB_DET_CC_NONDET		5
 #define	MB_DET_ERRONEOUS		6
 #define	MB_DET_FAILURE			7
+	/*
+	** 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_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 {
@@ -111,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;
@@ -125,19 +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		proc_id;
+			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;
@@ -159,11 +170,23 @@
 #define	MB_CONSID_BASE_TYPE_INFO_CONST	6
 #define	MB_CONSID_CHAR_CONST		7
 
+/*
+** 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_Bytecode_Addr addr;
+} MB_Label;
+
 typedef union MB_Bytecode_Arg_tag {
 	struct {
-		MB_CString	pred_name;	/* XXX: malloc */
+		MB_CString	pred_name;
 		MB_Short	pred_arity;
-		MB_Byte		is_func;
+		MB_Bool		is_func;
 		MB_Short	proc_count;
 	} enter_pred;
 
@@ -171,19 +194,24 @@
 	} 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_list; /* XXX: malloc */
+		MB_CString	*var_info;
 		
-		/* index onto label heap for label indexes
-		 * (not in the file) */
+		/*
+		** index onto label heap for label indexes
+		** (not in the file)
+		*/
 		MB_Word		label_index; 	
 	} enter_proc;
 
 	struct {
+		/* start of proc (not in file) */
+		MB_Bytecode_Addr proc_start;
 	} endof_proc;
 
 	struct {
@@ -191,67 +219,89 @@
 	} label;
 
 	struct {
-		MB_Short	end_label;
+		MB_Label end_label;
 	} enter_disjunction;
 
 	struct {
 	} endof_disjunction;
 
 	struct {
-		MB_Short	next_label;
+		MB_Label next_label;
 	} enter_disjunct;
 
 	struct {
-		MB_Short	label; /* XXX: what's label for? */
+		MB_Label end_label;
 	} endof_disjunct;
 
 	struct {
 		MB_Short	var;
-		MB_Short	end_label;
+		MB_Label	end_label;
 	} enter_switch;
 
 	struct {
+
 	} endof_switch;
 
 	struct {
 		MB_Cons_id	cons_id;
-		MB_Short	next_label;
+		MB_Label	next_label;
+
+		/* filled in at load time */
+		MB_Short	var;
 	} enter_switch_arm;
 
 	struct {
-		MB_Short	label;	/* XXX: what's this label for? */
+		MB_Label	end_label;
 	} endof_switch_arm;
 
 	struct {
-		MB_Short	else_label;
-		MB_Short	end_label;
+		MB_Label	else_label;
+		MB_Label	end_label;
 		MB_Short	frame_ptr_tmp;
 	} enter_if;
 
+	/* 
+	** identical to enter_else: if you change this, modify instr_else
+	** to reflect
+	*/
 	struct {
 		MB_Short	frame_ptr_tmp;
 	} enter_then;
 	
 	struct {
-		MB_Short	follow_label;
-	} endof_then;	/* XXX: should rename to enter_else */
+		MB_Label	follow_label;
+	} endof_then;
+
+	/* 
+	** identical to enter_then: if you change this, modify instr_then
+	** to reflect
+	*/
+	struct {
+		MB_Short	frame_ptr_tmp;
+	} enter_else;
 
 	struct {
+
 	} endof_if;
 
 	struct {
-		MB_Short	end_label;
+		MB_Short	frame_ptr_tmp;
+		MB_Label	end_label;
 	} enter_negation;
 
 	struct {
+		MB_Short	frame_ptr_tmp;
+	} endof_negation_goal;
+
+	struct {
 	} endof_negation;
 
 	struct {
-		MB_Short	temp;	
+		MB_Short	frame_ptr_tmp;
 	} enter_commit;
 
 	struct {
-		MB_Short	temp;	
+		MB_Short	frame_ptr_tmp;
 	} endof_commit;
 
 	struct {
@@ -268,28 +318,28 @@
 		MB_Short	to_var;
 		MB_Cons_id	consid;
 		MB_Short	list_length;
-		MB_Short	*var_list;	/* XXX: malloc */
+		MB_Short	*var_list;
 	} construct;
 
 	struct {
 		MB_Short	from_var;
 		MB_Cons_id	consid;
 		MB_Short	list_length;
-		MB_Short	*var_list;	/* XXX: malloc */
+		MB_Short	*var_list;
 	} deconstruct;
 
 	struct {
 		MB_Short	to_var;
 		MB_Cons_id	consid;
 		MB_Short	list_length;
-		MB_Var_dir	*var_dir_list;/* XXX: malloc */	
+		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_list;/* XXX: malloc */
+		MB_Var_dir	*var_dir;
 	} complex_deconstruct;
 
 	struct {
@@ -303,13 +353,13 @@
 	} pickup_arg;
 		
 	struct {
-		MB_CString	module_id;	/* XXX: malloc */
-		MB_CString	pred_id;	/* XXX: malloc */
+		MB_CString	module_name;
+		MB_CString	pred_name;
 		MB_Short	arity;
-		MB_Byte		proc_id;
-
-		/* 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  {
@@ -359,6 +409,7 @@
 
 	struct {
 	} not_supported;
+
 } MB_Bytecode_Arg;
 
 typedef struct MB_Bytecode_struct {
@@ -384,7 +435,6 @@
 #define	MB_BC_endof_switch_arm		12
 #define	MB_BC_enter_if			13
 #define	MB_BC_enter_then		14
-/* XXX: enter_else would be a better name than endof_then */
 #define	MB_BC_endof_then		15
 #define	MB_BC_endof_if			16
 #define	MB_BC_enter_negation		17
@@ -410,30 +460,34 @@
 #define	MB_BC_fail			37
 #define	MB_BC_context			38
 #define	MB_BC_not_supported		39
+#define	MB_BC_enter_else		40
+#define	MB_BC_endof_negation_goal	41
 
 /* These are used internally by the interpreter */
 /* all codes above MB_BC_debug are debugging values */
-#define MB_BC_debug			254
-#define	MB_BC_debug_trap		254
-#define	MB_BC_debug_invalid		255
-/*#define	MB_BC_noop			255*/
+#define	MB_BC_debug			0x3d
+#define	MB_BC_debug_trap		0x3e
+#define	MB_BC_debug_invalid		0x3f
+/*
+** Note that the limit to these is determined in mb_module.c by the
+** number of bits allocated to an id
+*/
 
 /*
- *	Read the next bytecode from the stream fp.
- *	If no bytecode can be read, return FALSE.
- *	Otherwise, return TRUE.
- */
+**	Read the next bytecode from the stream fp.
+**	If no bytecode can be read, return FALSE.
+**	Otherwise, return TRUE.
+*/
 MB_Bool
 MB_read_bytecode(FILE *fp, MB_Bytecode *bc_p);
 
 /*
- *	Read the bytecode version number from the stream fp.
- *	If the version number cannot be read, return FALSE.
- *	Otherwise, return TRUE.
- */
+**	Read the bytecode version number from the stream fp.
+**	If the version number cannot be read, return FALSE.
+**	Otherwise, return TRUE.
+*/
 MB_Bool
 MB_read_bytecode_version_number(FILE *fp, MB_Short *version_number_p);
 
 #endif	/* MB_BYTECODE_H */
-
 
--- ../bytecode.old/mb_bytecode.c	Wed Jan 24 18:42:22 2001
+++ mb_bytecode.c	Mon Jan 29 17:49:01 2001
@@ -1,10 +1,9 @@
 
 /*
-** Copyright (C) 2000 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.
 **
-** $Id: mb_bytecode.c,v 1.1 2001/01/24 07:42:22 lpcam Exp $
 */
 
 /* Imports */
@@ -14,15 +13,13 @@
 
 #include	"mb_bytecode.h"
 #include	"mb_mem.h"
+#include	"mb_module.h"
 #include	"mb_util.h"
 
 /* Exported definitions */
 
 /* Local declarations */
 
-static char
-rcs_id[]	= "$Id: mb_bytecode.c,v 1.1 2001/01/24 07:42:22 lpcam Exp $";
-
 /* 
 ** All read functions return true if successful
 */
@@ -70,7 +67,6 @@
 	MB_Byte	c;
 
 	if (! MB_read_byte(fp, &c)) {
-		MB_util_error("Unable to read bytecode id\n");
 		return FALSE;
 	}
 
@@ -92,6 +88,7 @@
 				bc_p->opt.enter_pred.pred_arity = pred_arity;
 				bc_p->opt.enter_pred.is_func = is_func;
 				bc_p->opt.enter_pred.proc_count = proc_count;
+
 				return TRUE;
 			}
 			break;
@@ -103,37 +100,44 @@
 		{
 			MB_Byte		proc_id;
 			MB_Determinism	det;
-			MB_Short	label_count, temp_count, list_length;
-			MB_CString	*var_info_list;
+			MB_Short	label_count, end_label;
+			MB_Short	temp_count, list_length;
+			MB_CString	*var_info;
 			
 			if (MB_read_byte(fp, &proc_id) &&
 				MB_read_byte(fp, &det) &&
 				MB_read_short(fp, &label_count) &&
+				MB_read_short(fp, &end_label) &&
 				MB_read_short(fp, &temp_count) &&
 				MB_read_short(fp, &list_length))
 			{
 				int 		i;
 				MB_CString	str;
 
-				var_info_list = MB_new_array(MB_CString,
-					list_length);
+				var_info = (list_length == 0) ?  NULL :
+					MB_CODE_DATA_ALLOC(MB_CString,
+							list_length); 
 
 				for (i = 0; i < list_length; i++) {
 					if (MB_read_cstring(fp, &str)) {
-						var_info_list[i] = str;
+						var_info[i] = str;
 					} else {
-						MB_fatal("XXX: decent message");
+						MB_fatal("enter_proc var"
+							" read error");
 					}
 				}
 
-				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 =
+					end_label;
 				bc_p->opt.enter_proc.temp_count = temp_count;
 				bc_p->opt.enter_proc.list_length = list_length;
-				bc_p->opt.enter_proc.var_info_list =
-					var_info_list;
+				bc_p->opt.enter_proc.var_info = var_info;
 				return TRUE;
+			} else {
+				MB_fatal("enter_proc read error");
 			}
 			break;
 		}
@@ -157,7 +161,7 @@
 			MB_Short	end_label;
 
 			if (MB_read_short(fp, &end_label)) {
-				bc_p->opt.enter_disjunction.end_label =
+				bc_p->opt.enter_disjunction.end_label.index =
 					end_label;
 				return TRUE;
 			} else {
@@ -173,7 +177,7 @@
 			MB_Short	next_label;
 
 			if (MB_read_short(fp, &next_label)) {
-				bc_p->opt.enter_disjunct.next_label =
+				bc_p->opt.enter_disjunct.next_label.index =
 					next_label;
 				return TRUE;
 			} else {
@@ -186,10 +190,11 @@
 			MB_Short	label;
 
 			if (MB_read_short(fp, &label)) {
-				bc_p->opt.endof_disjunct.label = label;
+				bc_p->opt.endof_disjunct.end_label.index
+					= label;
 				return TRUE;
 			} else {
-				assert(FALSE); /*XXX*/
+				MB_fatal("endof_disjunct read error");
 			}
 			break;
 		}
@@ -201,10 +206,11 @@
 				MB_read_short(fp, &end_label))
 			{
 				bc_p->opt.enter_switch.var = var;
-				bc_p->opt.enter_switch.end_label = end_label;
+				bc_p->opt.enter_switch.end_label.index =
+					end_label;
 				return TRUE;
 			} else {
-				MB_fatal("enter_switch malformed");
+				MB_fatal("enter_switch read error");
 			}
 			break;
 		}
@@ -219,11 +225,11 @@
 				MB_read_short(fp, &next_label))
 			{
 				bc_p->opt.enter_switch_arm.cons_id = cons_id;
-				bc_p->opt.enter_switch_arm.next_label 
-					= next_label;
+				bc_p->opt.enter_switch_arm.next_label.index = 
+					next_label;
 				return TRUE;
 			} else {
-				assert(FALSE); /* XXX */
+				MB_fatal("enter_switch_arm read error");
 			}
 			break;
 		}
@@ -231,11 +237,11 @@
 			MB_Short	label;
 
 			if (MB_read_short(fp, &label)) {
-				bc_p->opt.endof_switch_arm.label =
+				bc_p->opt.endof_switch_arm.end_label.index =
 					label;
 				return TRUE;
 			} else {
-				assert(FALSE); /*XXX*/
+				MB_fatal("endof_switch_arm read error");
 			}
 			break;
 		}
@@ -246,15 +252,15 @@
 				MB_read_short(fp, &end_label) &&
 				MB_read_short(fp, &frame_ptr_tmp))
 			{
-				bc_p->opt.enter_if.else_label =
+				bc_p->opt.enter_if.else_label.index =
 					else_label;
-				bc_p->opt.enter_if.end_label =
+				bc_p->opt.enter_if.end_label.index =
 					end_label;
 				bc_p->opt.enter_if.frame_ptr_tmp =
 					frame_ptr_tmp;
 				return TRUE;
 			} else {
-				assert(FALSE); /* XXX */
+				MB_fatal("enter_if read error");
 			}
 			break;
 		}
@@ -267,59 +273,96 @@
 					frame_ptr_tmp;
 				return TRUE;
 			} else {
-				assert(FALSE);	/* XXX */
+				MB_fatal("enter_then read error");
 			}
 			break;
 		}
-		case MB_BC_endof_then: {	/* XXX: change to enter_else */
+		case MB_BC_endof_then: {
 			MB_Short	follow_label;
 
 			if (MB_read_short(fp, &follow_label)) {
-				bc_p->opt.endof_then.follow_label =
+				bc_p->opt.endof_then.follow_label.index =
 					follow_label;
 				return TRUE;
 			} else {
-				assert(FALSE); /* XXX */
+				MB_fatal("endof_then read error");
 			}
 			break;
 		}
+
+		case MB_BC_enter_else: {
+			MB_Short	frame_ptr_tmp;
+
+			if (MB_read_short(fp, &frame_ptr_tmp))
+			{
+				bc_p->opt.enter_else.frame_ptr_tmp =
+					frame_ptr_tmp;
+				return TRUE;
+			} else {
+				MB_fatal("enter_else read error");
+			}
+			break;
+		}
+				       
 		case MB_BC_endof_if:
 			return TRUE;
 			break;
+			
 		case MB_BC_enter_negation: {
+			MB_Short	frame_ptr_tmp;
 			MB_Short	end_label;
 		
-			if (MB_read_short(fp, &end_label)) {
-				bc_p->opt.enter_negation.end_label =
+			if (MB_read_short(fp, &frame_ptr_tmp) &&
+				MB_read_short(fp, &end_label))
+			{
+				bc_p->opt.enter_negation.frame_ptr_tmp =
+					frame_ptr_tmp;
+				bc_p->opt.enter_negation.end_label.index =
 					end_label;
 				return TRUE;
 			} else {
-				assert(FALSE); /*XXX*/
+				MB_fatal("enter_negation read error");
+			}
+			break;
+		}
+		case MB_BC_endof_negation_goal: {
+			MB_Short	frame_ptr_tmp;
+		
+			if (MB_read_short(fp, &frame_ptr_tmp))
+			{
+				bc_p->opt.endof_negation_goal.frame_ptr_tmp =
+					frame_ptr_tmp;
+				return TRUE;
+			} else {
+				MB_fatal("enter_negation_goal read error");
 			}
 			break;
 		}
 		case MB_BC_endof_negation:
 			return TRUE;
 			break;
+			
 		case MB_BC_enter_commit: {
-			MB_Short	temp;
+			MB_Short	frame_ptr_tmp;
 			
-			if (MB_read_short(fp, &temp)) {
-				bc_p->opt.enter_commit.temp = temp;
+			if (MB_read_short(fp, &frame_ptr_tmp)) {
+				bc_p->opt.enter_commit.frame_ptr_tmp =
+					frame_ptr_tmp;
 				return TRUE;
 			} else {
-				assert(FALSE); /*XXX */
+				MB_fatal("enter_commit read error");
 			}
 			break;
 		}
 		case MB_BC_endof_commit: {
-			MB_Short	temp;
+			MB_Short	frame_ptr_tmp;
 			
-			if (MB_read_short(fp, &temp)) {
-				bc_p->opt.endof_commit.temp = temp;
+			if (MB_read_short(fp, &frame_ptr_tmp)) {
+				bc_p->opt.endof_commit.frame_ptr_tmp
+					= frame_ptr_tmp;
 				return TRUE;
 			} else {
-				assert(FALSE); /*XXX */
+				MB_fatal("endof_commit read error");
 			}
 			break;
 		}
@@ -334,7 +377,7 @@
 					from_var;
 				return TRUE;
 			} else {
-				assert(FALSE); /* XXX */
+				MB_fatal("assign read error");
 			}
 			break;
 		}
@@ -348,7 +391,7 @@
 				bc_p->opt.test.var2 = var2;
 				return TRUE;
 			} else {
-				assert(FALSE); /* XXX */
+				MB_fatal("test read error");
 			}
 			break;
 		}
@@ -362,9 +405,11 @@
 				MB_read_cons_id(fp, &consid) &&
 				MB_read_short(fp, &list_length))
 			{
-				MB_Short	i;
+				MB_Short i;
 
-				var_list = MB_new_array(MB_Short, list_length);
+				var_list = (list_length == 0) ?  NULL : 
+					MB_CODE_DATA_ALLOC(MB_Short,
+							list_length);
 
 				for (i = 0; i < list_length; i++) {
 					MB_Short	var;
@@ -372,17 +417,19 @@
 					if (MB_read_short(fp, &var)) {
 						var_list[i] = var;
 					} else {
-						assert(FALSE); /*XXX*/
+						MB_fatal("construct var"
+							" read error");
 					}
 				}
 
+
 				bc_p->opt.construct.to_var = to_var;
 				bc_p->opt.construct.consid = consid;
 				bc_p->opt.construct.list_length = list_length;
 				bc_p->opt.construct.var_list = var_list;
 				return TRUE;
 			} else {
-				assert(FALSE); /* XXX */
+				MB_fatal("construct read error");
 			}
 			break;
 		}
@@ -396,9 +443,11 @@
 				MB_read_cons_id(fp, &consid) &&
 				MB_read_short(fp, &list_length))
 			{
-				MB_Short	i;
+				MB_Short i;
 
-				var_list = MB_new_array(MB_Short, list_length);
+				var_list = (list_length == 0) ?  NULL : 
+					MB_CODE_DATA_ALLOC(MB_Short,
+							list_length);
 
 				for (i = 0; i < list_length; i++) {
 					MB_Short	var;
@@ -406,7 +455,8 @@
 					if (MB_read_short(fp, &var)) {
 						var_list[i] = var;
 					} else {
-						assert(FALSE); /*XXX*/
+						MB_fatal("deconstruct var"
+							" read error");
 					}
 				}
 
@@ -415,11 +465,10 @@
 				bc_p->opt.deconstruct.consid = consid;
 				bc_p->opt.deconstruct.list_length = 
 					list_length;
-				bc_p->opt.deconstruct.var_list = 
-					var_list;
+				bc_p->opt.deconstruct.var_list = var_list;
 				return TRUE;
 			} else {
-				assert(FALSE); /* XXX */
+				MB_fatal("deconstruct read error");
 			} 
 			break;
 		}
@@ -436,13 +485,15 @@
 				MB_Var_dir	var_dir;
 				int		i;
 
-				var_dir_list = MB_new_array(MB_Var_dir,
-					list_length);
+				var_dir_list = MB_CODE_DATA_ALLOC(MB_Var_dir,
+								list_length);
+
 				for (i = 0; i < list_length ; i++) {
 					if (MB_read_var_dir(fp, &var_dir)) {
 						var_dir_list[i] = var_dir;
 					} else {
-						assert(FALSE); /*XXX*/
+						MB_fatal("complex_construct"
+							" var read error");
 					}
 				}
 
@@ -450,9 +501,11 @@
 				bc_p->opt.complex_construct.consid = consid;
 				bc_p->opt.complex_construct.list_length 
 					= list_length;
+				bc_p->opt.complex_construct.var_dir
+					= var_dir_list;
 				return TRUE;
 			} else {
-				assert(FALSE); /* XXX */
+				MB_fatal("complex_construct read error");
 			}
 			break;
 		}
@@ -469,13 +522,15 @@
 				MB_Var_dir	var_dir;
 				int		i;
 
-				var_dir_list = MB_new_array(MB_Var_dir,
-					list_length);
+				var_dir_list = MB_CODE_DATA_ALLOC(MB_Var_dir,
+								list_length);
+
 				for (i = 0; i < list_length; i++) {
 					if (MB_read_var_dir(fp, &var_dir)) {
 						var_dir_list[i] = var_dir;
 					} else {
-						assert(FALSE); /*XXX*/
+						MB_fatal("complex_deconstruct"
+							" var read error");
 					}
 				}
 				bc_p->opt.complex_deconstruct.from_var =
@@ -483,11 +538,11 @@
 				bc_p->opt.complex_deconstruct.consid = consid;
 				bc_p->opt.complex_deconstruct.list_length =
 					list_length;
-				bc_p->opt.complex_deconstruct.var_dir_list =
+				bc_p->opt.complex_deconstruct.var_dir =
 					var_dir_list;
 				return TRUE;
 			} else {
-				assert(FALSE); /* XXX */
+				MB_fatal("complex_deconstruct read error");
 			}
 			break;
 		}
@@ -503,7 +558,7 @@
 					from_var;
 				return TRUE;
 			} else {
-				assert(FALSE); /* XXX */
+				MB_fatal("place_arg read error");
 			}
 			break;
 		}
@@ -520,7 +575,7 @@
 					to_var;
 				return TRUE;
 			} else {
-				assert(FALSE); /* XXX */
+				MB_fatal("pickup_arg read error");
 			}
 			break;
 		}
@@ -528,22 +583,32 @@
 			MB_CString	module_id;
 			MB_CString	pred_id;
 			MB_Short	arity;
+			MB_Byte		is_func;
 			MB_Byte		proc_id;
 
 			if (MB_read_cstring(fp, &module_id) &&
 				MB_read_cstring(fp, &pred_id) &&
 				MB_read_short(fp, &arity) &&
+				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.proc_id = proc_id;
+				bc_p->opt.call.is_func = is_func;
+				bc_p->opt.call.mode_num = proc_id;
+
+				/*
+				** 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 {
-				assert(FALSE); /*XXX*/
+				MB_fatal("call read error");
 			}
 			break;
 		}
@@ -568,7 +633,7 @@
 					det = det;
 				return TRUE;
 			} else {
-				assert(FALSE); /* XXX */
+				MB_fatal("higher_order_call read error");
 			}
 			break;
 		}
@@ -583,17 +648,13 @@
 				MB_read_op_arg(fp, &arg2) &&
 				MB_read_short(fp, &to_var))
 			{
-				bc_p->opt.builtin_binop.binop =
-					binop;
-				bc_p->opt.builtin_binop.arg1 =
-					arg1;
-				bc_p->opt.builtin_binop.arg2 =
-					arg2;
-				bc_p->opt.builtin_binop.to_var =
-					to_var;
+				bc_p->opt.builtin_binop.binop = binop;
+				bc_p->opt.builtin_binop.arg1 = arg1;
+				bc_p->opt.builtin_binop.arg2 = arg2;
+				bc_p->opt.builtin_binop.to_var = to_var;
 				return TRUE;
 			} else {
-				assert(FALSE); /* XXX */
+				MB_fatal("builtin_binop read error");
 			}
 			break;
 		}
@@ -611,7 +672,7 @@
 				bc_p->opt.builtin_unop.to_var = to_var;
 				return TRUE;
 			} else {
-				assert(FALSE); /* XXX */
+				MB_fatal("builtin_unop read error");
 			}
 			break;
 		}
@@ -629,7 +690,7 @@
 				bc_p->opt.builtin_bintest.arg2 = arg2;
 				return TRUE;
 			} else {
-				assert(FALSE); /* XXX */
+				MB_fatal("builtin_bintest read error");
 			}
 			break;
 		}
@@ -644,7 +705,7 @@
 				bc_p->opt.builtin_untest.arg = arg;
 				return TRUE;
 			} else {
-				assert(FALSE); /* XXX */
+				MB_fatal("builtin_untest read error");
 			}
 			break;
 		}
@@ -666,13 +727,14 @@
 					line_number;
 				return TRUE;
 			} else {
-				assert(FALSE); /* XXX */
+				MB_fatal("context read error");
 			}
 			break;
 		}
 		case MB_BC_not_supported:
 			return TRUE;
 			break;
+
 		default:
 			MB_fatal("bytecode.MB_read_bytecode: unknown bytecode");
 			break;
@@ -708,7 +770,7 @@
 		*short_p = (c0 << 8) | c1;
 		return TRUE;
 	} else {
-		assert(FALSE); /*XXX*/
+		MB_fatal("Unexpected file error reading short");
 		return FALSE; /* not reached */
 	}
 } /* MB_read_short */
@@ -775,7 +837,7 @@
 		*int_p = tmp_int;
 		return TRUE;
 	} else {
-		assert(FALSE); /*XXX*/
+		MB_fatal("Unexpected file error reading int");
 		return FALSE;
 	}
 } /* MB_read_int */
@@ -845,50 +907,71 @@
 }
 
 /*
-** MB_read_cstring MB_mallocs a string each time. The caller MB_frees it.
-** Starts assuming string won't be more than a certain length,
-** reallocates if it gets too long
+** Returned string is allocated with string routines MB_str_xxx
+** It is the responsibility of the caller to free it using MB_str_delete
 */
 static MB_Bool
 MB_read_cstring(FILE *fp, MB_CString *str_p)
 {
-	char		*str = NULL;
-	int		str_size = 128; /* highwater mark for str */
-	int		i = 0;
+	/*
+	** 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[64];
+	MB_Word	bufsize = sizeof(buffer);
+	char	*str = buffer;
+	
+	MB_Word		i = 0;
 	MB_Byte		c;
+	
+	do {
+		/* get the next char */
+		if (!MB_read_byte(fp, &c)) {
+			MB_fatal("Error reading C String from file");
+		}
 
-	/* Allocate initial static string */
-	str = MB_new_array(char, str_size);
+		/*
+		** 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 {
+				/*
+				** The current buffer is already malloced;
+				** realloc it
+				*/
+				str = MB_realloc(str, bufsize);
+			}
 
-	for (i=0;;) {
-		MB_Bool got_byte;
+			if (str == NULL) return FALSE;
+		}
 
-		got_byte = MB_read_byte(fp, &c);
+		str[i++] = c;
 
-		if (i + 1 > str_size) {
-			str_size *= 2; /* Double buffer size */
-			str = MB_resize_array(str, char, str_size);
-			assert(str != NULL); /* XXX */
-		}
-
-		if ('\0' == c || ! got_byte) {
-			int		str_len;
-			MB_CString	ret_str;
-
-			str[i] = '\0';
-			str_len = strlen(str);
-			ret_str = MB_new_array(char, str_len + 1);
-			strcpy(ret_str, str);
-			*str_p = ret_str;
-			MB_free(str);
-			return TRUE;
-		} else {
-			str[i] = c;
-			i++;
-		}
-	} /* end for */
-	assert(str != NULL);
-	MB_free(str);
+	} 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() */
 
 
@@ -917,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;
@@ -936,8 +1019,8 @@
 				cons_id_p->opt.int_const = int_const;
 				return TRUE;
 			} else {
-				MB_util_error("Unable to read constructor integer"
-						" constant\n");
+				MB_util_error("Unable to read constructor"
+						" integer constant\n");
 				return FALSE;
 			}
 			break;
@@ -949,8 +1032,8 @@
 				cons_id_p->opt.string_const = string_const;
 				return TRUE;
 			} else {
-				MB_util_error("Unable to read constructor string"
-						" constant\n");
+				MB_util_error("Unable to read constructor"
+						" string constant\n");
 				return FALSE;
 			}
 			break;
@@ -962,8 +1045,8 @@
 				cons_id_p->opt.float_const = float_const;
 				return TRUE;
 			} else {
-				MB_util_error("Unable to read constructor float"
-						" constant\n");
+				MB_util_error("Unable to read constructor"
+						" float constant\n");
 				return FALSE;
 			}
 			break;
@@ -972,17 +1055,20 @@
 			MB_CString	module_id;
 			MB_CString	pred_id;
 			MB_Short	arity;
+			MB_Byte		is_func;
 			MB_Byte		proc_id;
 
 			if (MB_read_cstring(fp, &module_id) &&
 				MB_read_cstring(fp, &pred_id) &&
 				MB_read_short(fp, &arity) &&
+				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.proc_id = proc_id;
+				cons_id_p->opt.pred_const.is_func = is_func;
+				cons_id_p->opt.pred_const.mode_num = proc_id;
 				return TRUE;
 			} else {
 				MB_util_error("Unable to read predicate"
@@ -1003,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 {
@@ -1027,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 =
@@ -1106,7 +1192,8 @@
 				tag_p->opt.pair.secondary = secondary;
 				return TRUE;
 			} else {
-				MB_util_error("Unable to read complicated tag\n");
+				MB_util_error(
+					"Unable to read complicated tag\n");
 				return FALSE;
 			}
 			break;
@@ -1133,7 +1220,7 @@
 			break;
 	} /* switch */
 
-	assert(FALSE);	/* not reached*/
+	assert(FALSE);	/* not reached */
 	return FALSE;
 } /* end MB_read_tag() */
 
@@ -1173,7 +1260,8 @@
 				op_arg_p->opt.var = var;
 				return TRUE;
 			} else {
-				MB_util_error("Unable to read variable argument\n");
+				MB_util_error("Unable to read variable"
+						" argument\n");
 				return FALSE;
 			}
 			break;
@@ -1210,9 +1298,8 @@
 			return FALSE;
 	} /* end switch */
 
-	assert(FALSE);	/* not reached*/
+	assert(FALSE);	/* not reached */
 	return FALSE;
 } /* end MB_read_op_arg() */
-
 
 
--- ../bytecode.old/mb_disasm.h	Wed Jan 24 18:42:23 2001
+++ mb_disasm.h	Mon Jan 29 18:46:58 2001
@@ -1,10 +1,9 @@
 
 /*
-** Copyright (C) 1997 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.
 **
-** $Id: mb_disasm.h,v 1.1 2001/01/24 07:42:23 lpcam Exp $
 */
 
 #ifndef MB_DISASM_H
@@ -14,17 +13,26 @@
 
 #include "mb_bytecode.h"
 #include "mb_machine.h"
+#include "mb_module.h"
 
-/* Fills a string buffer with the name of a bytecode
-** returns the new indent level after the instruction
+/*
+** 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_Bytecode bc, char* buffer, int buffer_len, int
indent_level);
+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);
+void MB_listing(MB_Machine_State *ms, FILE *fp, MB_Bytecode_Addr start,
+	MB_Bytecode_Addr end, MB_Word line_len);
 
-#endif	/* MB_DISASM_H */
+/* 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.old/mb_disasm.c	Wed Jan 24 18:42:23 2001
+++ mb_disasm.c	Tue Jan 30 16:55:28 2001
@@ -1,11 +1,9 @@
 
 /*
-** Copyright (C) 2000 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.
 **
-** $Id: mb_disasm.c,v 1.1 2001/01/24 07:42:23 lpcam Exp $
-**
 ** Contains functions for disassembling bytecodes into human readable form
 **
 */
@@ -14,68 +12,69 @@
 #include	<assert.h>
 #include	<ctype.h>
 #include	<string.h>
+#include	<stdio.h>
 
 #include	"mb_disasm.h"
+#include	"mb_module.h"
 #include	"mb_util.h"
 
-/* Exported definitions */
+#include	"mb_machine_def.h"
 
-int MB_str_bytecode(MB_Bytecode bc, char* buffer, int buffer_len, int
indent_level);
-void MB_listing(MB_Machine_State* ms, FILE* fp, MB_Word start, MB_Word end);
+/* Exported definitions */
 
-/* Local declarations */
+int MB_str_bytecode(MB_Machine_State *ms, MB_Bytecode_Addr addr,
+		char *buffer, int buffer_len, int indent_level);
 
-static char
-rcs_id[]	= "$Id: mb_disasm.c,v 1.1 2001/01/24 07:42:23 lpcam Exp $";
+void MB_listing(MB_Machine_State *ms, FILE *fp, MB_Bytecode_Addr start,
+	MB_Bytecode_Addr end, MB_Word line_len);
 
-/* Fills a string buffer with the name of a bytecode */
-int MB_str_bytecode(MB_Bytecode bc, char* buffer, int buffer_len, int
indent_level);
+/* 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; \
 				} \
@@ -91,31 +90,48 @@
 			}
 
 
-/* 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()
-
-/* Fills a string corresponding to a bytecode */
-/* returns indent level for subsequent instructions */
-/* if buffer is NULL then only returns change in indent level */
+/*
+** 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
+**
+** 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
+*/
+
 int
-MB_str_bytecode(MB_Bytecode bc, char* buffer, int buffer_len, int indent_level) 
+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(addr);
+	MB_Bytecode_Arg *bca = MB_code_get_arg(addr);
+
+	/* calculate indent changes */
 	int this_indent = indent_level;
 	int next_indent = indent_level;
-	switch (bc.id) {
+
+	switch (bc_id) {
 		case MB_BC_enter_pred:
 		case MB_BC_enter_proc:
 		case MB_BC_enter_disjunction:
@@ -130,6 +146,8 @@
 		case MB_BC_label:
 		case MB_BC_enter_then:
 		case MB_BC_endof_then:
+		case MB_BC_enter_else:
+		case MB_BC_endof_negation_goal:
 			this_indent--;
 			break;
 		case MB_BC_endof_pred:
@@ -169,249 +187,319 @@
 	}
 
 	if (next_indent < 0) next_indent = 0;
+	
+
+	/* if we only wanted to calculate the indents, return now */
+	if (buffer == NULL || buffer_len <= 0) return next_indent;
 
-	if (buffer == NULL) return next_indent;
+	
+	/* indicate det/nondet code */
+	/* 
+	PRINT()
+		"%c",
+		(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()
+		str_bytecode_name(bc_id)
+	ENDPRINT()
 
-	switch (bc.id) {
+	switch (bc_id) {
 		case MB_BC_enter_pred:
-			Print()
+			PRINT()
 				" %s %s/%d (%d procs)",
-				bc.opt.enter_pred.is_func ? "func" : "pred",
-				bc.opt.enter_pred.pred_name,
-				bc.opt.enter_pred.pred_arity,
-				bc.opt.enter_pred.proc_count
-			EndPrint()
+				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()
 			break;
+				
 		case MB_BC_endof_pred:
 			/* No args */
 			buffer[0] = 0;
 			break;
+			
 		case MB_BC_enter_proc: {
 			MB_Short	i;
 			MB_Short	len;
 			
-			Print()
-				" proc %d: %s, %d labels, %d temps, %d vars:", 
-				bc.opt.enter_proc.proc_id,
-				str_determinism_name(bc.opt.enter_proc.det),
-				bc.opt.enter_proc.label_count,
-				bc.opt.enter_proc.temp_count,
-				bc.opt.enter_proc.list_length
-			EndPrint()
+			PRINT()
+				" mode %d: [%s] [%d labels] [endlabel %p]"
+					" [%d temps] [%d vars]", 
+				(int) bca->enter_proc.mode_num,
+				str_determinism_name(bca->enter_proc.det),
+				bca->enter_proc.label_count,
+				bca->enter_proc.end_label.addr,
+				bca->enter_proc.temp_count,
+				bca->enter_proc.list_length
+			ENDPRINT()
 
-			len = bc.opt.enter_proc.list_length;
+			len = bca->enter_proc.list_length;
 			for (i = 0; i < len; i++) {
-				Print()
+				PRINT()
 					" %s",
-					bc.opt.enter_proc.var_info_list[i]
-				EndPrint()
+					bca->enter_proc.var_info[i]
+
+				ENDPRINT()
 			}
 			break;
 		}
 		case MB_BC_endof_proc:
-			/* No args */
+			PRINT()
+				" (%p)",
+				bca->endof_proc.proc_start
+			ENDPRINT()
 			break;
+			
 		case MB_BC_label:
-			Print()
+			PRINT()
 				" %d",
-				bc.opt.label.label
-			EndPrint()
+				(int) bca->label.label
+			ENDPRINT()
 			break;
+				
 		case MB_BC_enter_disjunction:
-			Print()
-				" %d",
-				bc.opt.enter_disjunction.end_label
-			EndPrint()
+			PRINT()
+				" [endlabel %p]",
+				bca->enter_disjunction.end_label.addr
+			ENDPRINT()
 			break;
+				
 		case MB_BC_endof_disjunction:
 			/* No args */
 			buffer[0] = 0;
 			break;
+			
 		case MB_BC_enter_disjunct:
-			Print()
-				" %d",
-				bc.opt.enter_disjunct.next_label
-			EndPrint()
+			PRINT()
+				" [nextlabel %p]",
+				bca->enter_disjunct.next_label.addr
+			ENDPRINT()
 			break;
+				
 		case MB_BC_endof_disjunct:
-			Print()
-				" %d",
-				bc.opt.endof_disjunct.label
-			EndPrint()
+			PRINT()
+				" [endlabel %p]",
+				bca->endof_disjunct.end_label.addr
+			ENDPRINT()
 			break;
+				
 		case MB_BC_enter_switch:
-			Print()
-				" on %d, label %d",
-				bc.opt.enter_switch.var,
-				bc.opt.enter_switch.end_label
-			EndPrint()
+			PRINT()
+				" [var %d] [endlabel %p]",
+				(int) bca->enter_switch.var,
+				bca->enter_switch.end_label.addr
+			ENDPRINT()
 			break;
+				
 		case MB_BC_endof_switch:
 			/* No args */
 			buffer[0] = 0;
 			break;
+			
 		case MB_BC_enter_switch_arm:
-			Print()
-				" "
-			EndPrint()
-
-			PrintCall(str_cons_id, bc.opt.enter_switch_arm.cons_id)
-
-			Print()
-				" %d",
-				bc.opt.enter_switch_arm.next_label
-			EndPrint()
+			PRINT()
+				" (on var %d) ",
+				(int) bca->enter_switch_arm.var
+			ENDPRINT()
+
+			PRINTCALL(str_cons_id, bca->enter_switch_arm.cons_id)
+
+			PRINT()
+				" [nextlabel %p]",
+				bca->enter_switch_arm.next_label.addr
+			ENDPRINT()
 			break;
+				
 		case MB_BC_endof_switch_arm:
-			Print()
-				" endlabel %d",
-				bc.opt.endof_switch_arm.label
-			EndPrint()
+			PRINT()
+				" [endlabel %p]",
+				bca->endof_switch_arm.end_label.addr
+			ENDPRINT()
 			break;
+				
 		case MB_BC_enter_if:
-			Print()
-				" else %d, end %d, frame %d",
-				bc.opt.enter_if.else_label,
-				bc.opt.enter_if.end_label,
-				bc.opt.enter_if.frame_ptr_tmp
-			EndPrint()
+			PRINT()
+				" [else %p] [end %p] [frame %d]",
+				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()
-				" %d",
-				bc.opt.enter_then.frame_ptr_tmp
-			EndPrint()
+			PRINT()
+				" [frame %d]",
+				(int) bca->enter_then.frame_ptr_tmp
+			ENDPRINT()
 			break;
+				
 		case MB_BC_endof_then:
-			Print()
-				" %d",
-				bc.opt.endof_then.follow_label
-			EndPrint()
+			PRINT()
+				" [follow %p]",
+				bca->endof_then.follow_label.addr
+			ENDPRINT()
 			break;
+
+		case MB_BC_enter_else:
+			PRINT()
+				" [frame %d]",
+				(int) bca->enter_else.frame_ptr_tmp
+			ENDPRINT()
+			break;
+
+				
 		case MB_BC_endof_if:
 			/* No args */
 			buffer[0] = 0;
 			break;
+			
 		case MB_BC_enter_negation:
-			printf(" %d", bc.opt.enter_negation.end_label);
+			PRINT()
+				" [frame %d] [endlabel %p]",
+				(int) bca->enter_negation.frame_ptr_tmp,
+				bca->enter_negation.end_label.addr
+			ENDPRINT()
 			break;
+
+		case MB_BC_endof_negation_goal:
+			PRINT()
+				" [frame %d]",
+				(int) bca->endof_negation_goal.frame_ptr_tmp
+			ENDPRINT()
+				
 		case MB_BC_endof_negation:
 			/* No args */
 			buffer[0] = 0;
 			break;
+			
 		case MB_BC_enter_commit:
-			Print()
-				" %d",
-				bc.opt.enter_commit.temp
-			EndPrint()
+			PRINT()
+				" [frame %d]",
+				(int) bca->enter_commit.frame_ptr_tmp
+			ENDPRINT()
 			break;
+				
 		case MB_BC_endof_commit:
-			Print()
-				" %d",
-				bc.opt.endof_commit.temp
-			EndPrint()
+			PRINT()
+				" [frame %d]",
+				(int) bca->endof_commit.frame_ptr_tmp
+			ENDPRINT()
 			break;
+				
 		case MB_BC_assign:
-			Print()
-				" %d %d",
-				bc.opt.assign.to_var,
-				bc.opt.assign.from_var
-			EndPrint()
+			PRINT()
+				" [var %d] <= [var %d]",
+				(int) bca->assign.to_var,
+				(int) bca->assign.from_var
+			ENDPRINT()
 			break;
+				
 		case MB_BC_test:
-			Print()
-				" %d %d",
-				bc.opt.test.var1,
-				bc.opt.test.var2
-			EndPrint()
+			PRINT()
+				" [var %d] == [var %d]",
+				(int) bca->test.var1,
+				(int) bca->test.var2
+			ENDPRINT()
 			break;
+				
 		case MB_BC_construct: {
 			MB_Short	len;
 			MB_Short	i;
 
-			Print()
-				" %d ",
-				bc.opt.construct.to_var
-			EndPrint()
-
-			PrintCall(str_cons_id,bc.opt.construct.consid)
-
-			len = bc.opt.construct.list_length;
-			Print()
-				" %d",
-				len
-			EndPrint()
+			PRINT()
+				" [var %d] <= ",
+				(int) bca->construct.to_var
+			ENDPRINT()
+
+			PRINTCALL(str_cons_id,bca->construct.consid)
+
+			len = bca->construct.list_length;
+			PRINT()
+				" [%d var%s%s",
+				(int) len,
+				(len != 0) ? "s" : "",
+				(len > 0)  ? ":" : ""
+			ENDPRINT()
 			for (i = 0; i < len; i++) {
-				Print()
+				PRINT()
 					" %d",
-					bc.opt.construct.var_list[i]
-				EndPrint()
+					(int) bca->construct.var_list[i]
+				ENDPRINT()
 				
 			}
+			PRINT()
+				"]"
+			ENDPRINT()
 			break;
 		}
 		case MB_BC_deconstruct: {
 			MB_Short	len;
 			MB_Short	i;
 
-			Print()
-				" %d ",
-				bc.opt.deconstruct.from_var
-			EndPrint()
+			PRINT()
+				" [var %d] ",
+				(int) bca->deconstruct.from_var
+			ENDPRINT()
 			
-			PrintCall(str_cons_id,bc.opt.deconstruct.consid)
+			PRINTCALL(str_cons_id,bca->deconstruct.consid)
 
-			len = bc.opt.deconstruct.list_length;
-			Print()
-				" %d",
-				len
-			EndPrint()
+			len = bca->deconstruct.list_length;
+			PRINT()
+				" [%d var%s%s",
+				(int) len,
+				(len != 0) ? "s" : "",
+				(len > 0)  ? ":" : ""
+			ENDPRINT()
 
 			for (i = 0; i < len; i++) {
-				Print()
+				PRINT()
 					" %d",
-					bc.opt.deconstruct.var_list[i]
-				EndPrint()
+					(int) bca->deconstruct.var_list[i]
+				ENDPRINT()
 				
 			}
+			PRINT()
+				"]"
+			ENDPRINT()
 			break;
 		}
 		case MB_BC_complex_construct: {
 			MB_Short	len;
 			MB_Short	i;
 
-			Print()
+			PRINT()
 				" %d ",
-				bc.opt.complex_construct.to_var
-			EndPrint()
+				(int) bca->complex_construct.to_var
+			ENDPRINT()
 
-			PrintCall(str_cons_id,bc.opt.complex_construct.consid);
+			PRINTCALL(str_cons_id,bca->complex_construct.consid);
 
-			len = bc.opt.complex_construct.list_length;
+			len = bca->complex_construct.list_length;
 			
-			Print()
-				" %d", len
-			EndPrint()
+			PRINT()
+				" %d", (int) len
+			ENDPRINT()
 
 			for (i = 0; i < len; i++) {
-				Print()
+				PRINT()
 					" "
-				EndPrint()
+				ENDPRINT()
 
-				PrintCall(str_var_dir,
-					bc.opt.complex_construct.var_dir_list[i])
+				PRINTCALL(str_var_dir,
+					bca->complex_construct.var_dir[i])
 			}
 			break;
 		}
@@ -419,139 +507,157 @@
 			MB_Short	len;
 			MB_Short	i;
 
-			Print()
+			PRINT()
 				" %d ",
-				bc.opt.complex_deconstruct.from_var
-			EndPrint()
+				(int) bca->complex_deconstruct.from_var
+			ENDPRINT()
 
-			PrintCall(str_cons_id,bc.opt.complex_deconstruct.consid);
+			PRINTCALL(str_cons_id,bca->complex_deconstruct.consid)
 
-			len = bc.opt.complex_deconstruct.list_length;
-			Print()
+			len = bca->complex_deconstruct.list_length;
+			PRINT()
 				" %d",
-				len
-			EndPrint()
+				(int) len
+			ENDPRINT()
 
 			for (i = 0; i < len; i++) {
-				Print()
+				PRINT()
 					" "
-				EndPrint()
+				ENDPRINT()
 
-				PrintCall(str_var_dir,
-					bc.opt.complex_deconstruct.var_dir_list[i])
+				PRINTCALL(str_var_dir,
+					bca->complex_deconstruct.var_dir[i])
 			}
 			break;
 		}
 		case MB_BC_place_arg:
-			Print()
-				": r[%d] <= slot %d",
-				bc.opt.place_arg.to_reg,
-				bc.opt.place_arg.from_var
-			EndPrint()
+			PRINT()
+				" [r%d] <= [var %d]",
+				(int) bca->place_arg.to_reg,
+				(int) bca->place_arg.from_var
+			ENDPRINT()
 			break;
+				
 		case MB_BC_pickup_arg:
-			Print()
-				": r[%d] => slot %d",
-				bc.opt.pickup_arg.from_reg,
-				bc.opt.pickup_arg.to_var
-			EndPrint()
+			PRINT()
+				" [r%d] => [var %d]",
+				(int) bca->pickup_arg.from_reg,
+				(int) bca->pickup_arg.to_var
+			ENDPRINT()
 			break;
+				
 		case MB_BC_call:
-			Print()
-				" %s %s %d %d (%08x)",
-				bc.opt.call.module_id,
-				bc.opt.call.pred_id,
-				bc.opt.call.arity,
-				bc.opt.call.proc_id,
-				bc.opt.call.adr
-			EndPrint()
+			PRINT()
+				" [%s %s__%s/%d mode %d (%s %p)]",
+				bca->call.is_func ? "func" : "pred",
+				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()
-				" %d %d %d %s",
-				bc.opt.higher_order_call.pred_var,
-				bc.opt.higher_order_call.in_var_count,
-				bc.opt.higher_order_call.out_var_count,
-				str_determinism_name(bc.opt.higher_order_call.det)
-			EndPrint()
+			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,
+				str_determinism_name(bca->higher_order_call.det)
+			ENDPRINT()
 			break;
+				
 		case MB_BC_builtin_binop:
-			Print()
+			PRINT()
 				": "
-			EndPrint()
+			ENDPRINT()
 
-			PrintCall(str_op_arg,bc.opt.builtin_binop.arg1)
+			PRINTCALL(str_op_arg,bca->builtin_binop.arg1)
 
-			Print()
+			PRINT()
 				" %s ", 
-				str_binop_name(bc.opt.builtin_binop.binop)
-			EndPrint()
+				str_binop_name(bca->builtin_binop.binop)
+			ENDPRINT()
 
-			PrintCall(str_op_arg,bc.opt.builtin_binop.arg2)
+			PRINTCALL(str_op_arg,bca->builtin_binop.arg2)
 
-			Print()
-				" => %d",
-				bc.opt.builtin_binop.to_var
-			EndPrint()
+			PRINT()
+				" => [var %d]",
+				(int) bca->builtin_binop.to_var
+			ENDPRINT()
 			break;
+				
 		case MB_BC_builtin_unop:
-			Print()
+			PRINT()
 				" %s ", 
-				str_unop_name(bc.opt.builtin_unop.unop)
-			EndPrint()
+				str_unop_name(bca->builtin_unop.unop)
+			ENDPRINT()
 
-			PrintCall(str_op_arg,bc.opt.builtin_unop.arg)
+			PRINTCALL(str_op_arg,bca->builtin_unop.arg)
 
-			Print()
+			PRINT()
 				" %d",
-				bc.opt.builtin_unop.to_var
-			EndPrint()
+				(int) bca->builtin_unop.to_var
+			ENDPRINT()
 			break;
+				
 		case MB_BC_builtin_bintest:
-			Print()
-				" %s ", 
-				str_binop_name(bc.opt.builtin_bintest.binop)
-			EndPrint()
 
-			PrintCall(str_op_arg,bc.opt.builtin_binop.arg1)
-
-			Print()
+			PRINT()
 				" "
-			EndPrint()
+			ENDPRINT()
+
+			PRINTCALL(str_op_arg,bca->builtin_binop.arg1)
+
+			PRINT()
+				" %s ", 
+				str_binop_name(bca->builtin_bintest.binop)
+			ENDPRINT()
 
-			PrintCall(str_op_arg,bc.opt.builtin_binop.arg2)
+			PRINTCALL(str_op_arg,bca->builtin_binop.arg2)
 			break;
+				
 		case MB_BC_builtin_untest:
-			Print()
+			PRINT()
 				" %s ", 
-				str_unop_name(bc.opt.builtin_untest.unop)
-			EndPrint()
-			PrintCall(str_op_arg,bc.opt.builtin_unop.arg)
+				str_unop_name(bca->builtin_untest.unop)
+			ENDPRINT()
+			PRINTCALL(str_op_arg,bca->builtin_unop.arg)
 			break;
+				
 		case MB_BC_semidet_succeed:
 			/* No args */
 			buffer[0] = 0;
 			break;
+			
 		case MB_BC_semidet_success_check:
 			/* No args */
 			buffer[0] = 0;
 			break;
+			
 		case MB_BC_fail:
 			/* No args */
 			buffer[0] = 0;
 			break;
+			
 		case MB_BC_context:
-			Print()
+			PRINT()
 				" %d",
-				bc.opt.context.line_number
-			EndPrint()
+				bca->context.line_number
+			ENDPRINT()
 			break;
+				
 		case MB_BC_not_supported:
 			/* No args */
 			buffer[0] = 0;
 			break;
+
 		default:
-			assert(FALSE); /*XXX*/
+			MB_fatal("Attempt to disassemble unknown bytecode");
 			break;
 	} /* end switch */
 
@@ -560,143 +666,147 @@
 } /* 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()
+		"["
+	ENDPRINT()
 	switch (cons_id.id) {
 		case MB_CONSID_CONS: {
-			Print()
-				"functor %s %s %d ",
-				cons_id.opt.cons.module_id,
+			PRINT()
+				"functor %s__%s/%d ",
+				cons_id.opt.cons.module_name,
 				cons_id.opt.cons.string,
-				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:
-			/*
-			** (This comment is labelled "CAST COMMENT".
-			** If you remove this comment, also
-			** remove references to it in this file.
-			** Search for "CAST COMMENT".)
-			**
-			** XXX: The cast to `long' in the following code
-			** is needed to remove a warning. `int_const' has
-			** type `Integer', but Integer may be typedef'ed
-			** to `int', `long', `long long' or whatever.
-			** The correct solution may be to define a
-			** format string for Integer in conf.h.
-			*/
-			Print()
-				"int_const %ld",
-				(long) 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()
-				"string_const "
-			EndPrint()
-			buffer[buffer_len-1] = 0; /* snprintf may not do it */
+			PRINT()
+				"string_const"
+			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 %d %d",
-				"pred_const ",
-				cons_id.opt.pred_const.module_id,
-				cons_id.opt.pred_const.pred_id,
-				cons_id.opt.pred_const.arity,
-				cons_id.opt.pred_const.proc_id
-			EndPrint()
+			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_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,
-				cons_id.opt.code_addr_const.arity,
-				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()
-				"%s %s %s %d",
-				"base_type_info_const ",
-				cons_id.opt.base_type_info_const.module_id,
+			PRINT()
+				"%s %s__%s/%d",
+				"base_type_info_const",
+				cons_id.opt.base_type_info_const.module_name,
 				cons_id.opt.base_type_info_const.type_name,
-				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 ",
+					"char_const",
 					cons_id.opt.char_const.ch
-				EndPrint()
+				ENDPRINT()
 			} else {
-				Print()
-					"%s %2X",
-					"char_const ",
-					(int)cons_id.opt.char_const.ch
-				EndPrint()
+				PRINT()
+					"%s %d (0x%02X)",
+					"char_const",
+					(int) cons_id.opt.char_const.ch,
+					(int) cons_id.opt.char_const.ch
+				ENDPRINT()
 			}
 			break;
 		default:
-			assert(FALSE); /*XXX*/
+			MB_fatal("Attempt to disassemble unknown cons");
 			break;
 	} /* end switch */
+	PRINT()
+		"]"
+	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) {
 		case MB_TAG_SIMPLE:
 			snprintf(buffer, buffer_len,
-				"%s %d", "simple_tag", tag.opt.primary);
+				"%s %d",
+				"simple_tag",
+				(int) tag.opt.primary);
 			break;
 		case MB_TAG_COMPLICATED:
-			/*
-			** See comment labelled "CAST COMMENT".
-			*/
 			snprintf(buffer, buffer_len,
-				"%s %d %ld", "complicated_tag", 
-				tag.opt.pair.primary, 
-				(long) tag.opt.pair.secondary);
+				"%s %d %ld",
+				"complicated_tag", 
+				(int) tag.opt.pair.primary, 
+				(long int) tag.opt.pair.secondary);
 			break;
 		case MB_TAG_COMPLICATED_CONSTANT:
-			/*
-			** See comment labelled "CAST COMMENT".
-			*/
 			snprintf(buffer, buffer_len,
-				"%s %d %ld", "complicated_constant_tag", 
-				tag.opt.pair.primary, 
-				(long) tag.opt.pair.secondary);
+				"%s %d %ld",
+				"complicated_constant_tag", 
+				(int) tag.opt.pair.primary, 
+				(long int) tag.opt.pair.secondary);
 			break;
 		case MB_TAG_ENUM:
 			snprintf(buffer, buffer_len,
-				"%s %d", "enum_tag", tag.opt.enum_tag);
+				"%s %d",
+				"enum_tag",
+				(int) tag.opt.enum_tag);
 			break;
 		case MB_TAG_NONE:
 			snprintf(buffer, buffer_len,
-				"%s", "no_tag");
+				"%s",
+				"no_tag");
 			break;
 		default:
 			MB_util_error("Invalid tag: %d\n", tag.id);
-			assert(FALSE); /*XXX*/
+			assert(FALSE); /* XXX */
 			break;
 	} /* end switch */
 	
@@ -705,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",
@@ -724,7 +834,7 @@
 	"endof_switch_arm",
 	"enter_if",
 	"enter_then",
-	"endof_then",	/* XXX: change to enter_else */
+	"endof_then",
 	"endof_if",
 	"enter_negation",
 	"endof_negation",
@@ -736,7 +846,7 @@
 	"deconstruct",
 	"complex_construct",
 	"complex_deconstruct",
-	"place_arg",
+	"place_arg ",
 	"pickup_arg",
 	"call",
 	"higher_order_call",
@@ -748,23 +858,25 @@
 	"semidet_success_check",
 	"fail",
 	"context",
-	"not_supported"
+	"not_supported",
+	"enter_else",
+	"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",
@@ -777,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",
@@ -807,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[] = {
 	"+",
 	"-",
@@ -862,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() */
 
@@ -877,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 */
@@ -926,80 +1038,92 @@
 } /* 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()
-				"var %d",
+			PRINT()
+				"[var %d]",
 				op_arg.opt.var
-			EndPrint()
+			ENDPRINT()
 			break;
 		case MB_ARG_INT_CONST:
-			/*
-			** See comment labelled "CAST COMMENT".
-			*/
-			Print()
-				"int %ld",
-				(long) 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()
-				"float %f",
+			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[73];
-	MB_Word i;
+	char buffer[256];
+	MB_Bytecode_Addr i;
 	MB_Word	indent = 0;
-	MB_Word ip = MB_ip_get(ms);
+	MB_Bytecode_Addr ip = MB_ip_get(ms);
+
+	MB_SAY("linelen: %d\n", line_len);
+
+	start = MB_code_range_clamp(start);
+	end = MB_code_range_clamp(end);
 
-	/* backtrack to the previous predicate */
-	/* and assume that it is at indent level 0 */
-	i = MB_code_get_pred_adr(ms, start);
-
-	/* work out the indent level at the start */
-	while (i != start) {
-		indent = MB_str_bytecode(MB_code_get(ms, i), NULL, 0, indent);
-		i++;
+	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_addr(start);
+
+	if (i != MB_CODE_INVALID_ADR) {
+		/* work out the indent level at the start */
+		while (i != start) {
+			indent = MB_str_bytecode(ms,
+					i, NULL, 0, indent);
+			i++;
+		}
 	}
 
 	/* Show the code */
 	for (; i != end+1; i++) {
-		if (i < 0 || i >= MB_code_size(ms)) {
-			fprintf(fp, "   %04x (????)\n", i & 0xffff);
-		} else {
-			indent = MB_str_bytecode(MB_code_get(ms, i),
-					buffer, sizeof(buffer), indent);
-			fprintf(fp, "%s%04x %s\n",
-				(i == ip) ? "-> " : "   ",
-				i,
-				buffer);
-		}
+		indent = MB_str_bytecode(ms, i,
+				buffer, line_len, indent);
+		fprintf(fp, "%s%p %s\n",
+			(i == ip) ? "-> " : "   ",
+			i,
+			buffer);
 	}
 }
-
-
--------------------------------------------------------------------------
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