diff options
Diffstat (limited to 'mixlib')
| -rw-r--r-- | mixlib/Makefile.am | 5 | ||||
| -rw-r--r-- | mixlib/mix_config.c | 19 | ||||
| -rw-r--r-- | mixlib/mix_predicate.c | 207 | ||||
| -rw-r--r-- | mixlib/mix_predicate.h | 75 | ||||
| -rw-r--r-- | mixlib/mix_predicate_list.c | 111 | ||||
| -rw-r--r-- | mixlib/mix_predicate_list.h | 61 | ||||
| -rw-r--r-- | mixlib/mix_vm.c | 41 | ||||
| -rw-r--r-- | mixlib/mix_vm.h | 11 | ||||
| -rw-r--r-- | mixlib/mix_vm_command.c | 9 | ||||
| -rw-r--r-- | mixlib/xmix_vm.h | 3 | 
10 files changed, 528 insertions, 14 deletions
diff --git a/mixlib/Makefile.am b/mixlib/Makefile.am index 2c1f818..475fad3 100644 --- a/mixlib/Makefile.am +++ b/mixlib/Makefile.am @@ -29,7 +29,10 @@ libmix_a_SOURCES = mix.h mix.c \  		   mix_src_file.c mix_src_file.h \                     mix_vm_clock.c mix_vm_clock.h \  		   mix_vm_command.c mix_vm_command.h \ -		   mix_config.c mix_config.h +		   mix_config.c mix_config.h \ +                   mix_predicate.c mix_predicate.h \ +                   mix_predicate_list.c mix_predicate_list.h + diff --git a/mixlib/mix_config.c b/mixlib/mix_config.c index ba9ad19..fd3505e 100644 --- a/mixlib/mix_config.c +++ b/mixlib/mix_config.c @@ -143,24 +143,28 @@ mix_config_get_integer (const mix_config_t *config, const gchar *key)  void  mix_config_update (mix_config_t *config, const gchar *key, const gchar *value)  { -  gpointer tmp = NULL; +  gpointer okey = NULL; +  gpointer oval = NULL;    g_return_if_fail (config != NULL);    g_return_if_fail (key != NULL);    g_return_if_fail (value != NULL); -  tmp = g_hash_table_lookup (config->items, key); -  if (tmp) +  if (g_hash_table_lookup_extended (config->items, key, &okey, &oval))      { -      g_free (tmp); -      tmp = (gpointer)key; +      if (oval != value) +	{ +	  g_free (oval); +	  oval = (gpointer)g_strdup (value); +	}      }    else      { -      tmp = (gpointer)g_strdup (key); +      okey = (gpointer)g_strdup (key); +      oval = (gpointer)g_strdup (value);      } -  g_hash_table_insert (config->items, tmp, g_strdup (value)); +  g_hash_table_insert (config->items, okey, oval);  }  void @@ -170,7 +174,6 @@ mix_config_update_integer (mix_config_t *config, const gchar *key, gint value)    g_return_if_fail (config != NULL);    g_return_if_fail (key != NULL); -  g_return_if_fail (value != NULL);    val = g_strdup_printf ("%d", value);    mix_config_update (config, key, val); diff --git a/mixlib/mix_predicate.c b/mixlib/mix_predicate.c new file mode 100644 index 0000000..544da64 --- /dev/null +++ b/mixlib/mix_predicate.c @@ -0,0 +1,207 @@ +/* -*-c-*- -------------- mix_predicate.c : + * Implementation of the functions declared in mix_predicate.h + * ------------------------------------------------------------------ + *  Last change: Time-stamp: "2001-07-16 01:15:51 jao" + * ------------------------------------------------------------------ + * Copyright (C) 2001 Free Software Foundation, Inc. + *   + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + *   + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + *   + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *   + */ + +#include "mix_vm.h" +#include "mix_predicate.h" + +/* predicate data */ +typedef union pred_data_t  +{ +  mix_word_t regA; +  mix_word_t regX; +  mix_short_t regI; +  mix_cmpflag_t cmp; +  gboolean over; +  mix_word_t mem; +} pred_data_t; + +/* the predicate function type */ +typedef gboolean (*mix_predicate_fun_t) (mix_predicate_t *pred, +					 const mix_vm_t *vm); + +/* the predicate type */ +struct mix_predicate_t +{ +  mix_predicate_type_t type; +  pred_data_t data; +  guint control; +}; + +/* predicate funcs */ +static gboolean +pred_func_rA (mix_predicate_t *pred, const mix_vm_t *vm)  +{ +  mix_word_t val = mix_vm_get_rA (vm); +  if (pred->data.regA == val) return FALSE; +  pred->data.regA = val; +  return TRUE; +} + +static gboolean +pred_func_rX (mix_predicate_t *pred, const mix_vm_t *vm)  +{ +  mix_word_t val = mix_vm_get_rX (vm); +  if (pred->data.regX == val) return FALSE; +  pred->data.regX = val; +  return TRUE; +} + +static gboolean +pred_func_rI (mix_predicate_t *pred, const mix_vm_t *vm)  +{ +  mix_short_t val = (pred->control == 0) ? mix_vm_get_rJ (vm) +    : mix_vm_get_rI (vm, pred->control); +  if (pred->data.regI == val) return FALSE; +  pred->data.regI = val; +  return TRUE; +} + +static gboolean  +pred_func_mem (mix_predicate_t *pred, const mix_vm_t *vm)  +{ +  mix_word_t val = +    mix_vm_get_addr_contents (vm, (mix_address_t)pred->control); +  if (pred->data.mem == val) return FALSE; +  pred->data.mem = val; +  return TRUE; +} + +static gboolean +pred_func_cmp (mix_predicate_t *pred, const mix_vm_t *vm)  +{ +  mix_cmpflag_t val = mix_vm_get_cmpflag (vm); +  if (pred->data.cmp == val) return FALSE; +  pred->data.cmp = val; +  return TRUE; +} + +static gboolean +pred_func_over (mix_predicate_t *pred, const mix_vm_t *vm)  +{ +  gboolean val = mix_vm_get_overflow (vm); +  if (pred->data.over == val) return FALSE; +  pred->data.over = val; +  return TRUE; +} + +static mix_predicate_fun_t PRED_FUNCS_[] = { +  pred_func_rA, pred_func_rX, pred_func_rI, pred_func_rI, pred_func_rI, +  pred_func_rI, pred_func_rI, pred_func_rI, pred_func_rI,  +  pred_func_over, pred_func_cmp, pred_func_mem +}; + +/* create predicates based on vm status */ +mix_predicate_t * +mix_predicate_new (mix_predicate_type_t type) +{ +  mix_predicate_t *result; +  g_return_val_if_fail (type <= MIX_PRED_MEM, NULL); +  result = g_new (mix_predicate_t, 1); +  result->type = type; +  result->data.regA = MIX_WORD_ZERO; +  if (type >= MIX_PRED_REG_I1 && type <= MIX_PRED_REG_I6) +    result->control = 1 + type - MIX_PRED_REG_I1; +  else +    result->control = 0; +  return result; +} + +/* delete a predicate */ +void +mix_predicate_delete (mix_predicate_t *predicate) +{ +  g_return_if_fail (predicate != NULL); +  g_free (predicate); +} + +/* test a predicate */ +gboolean +mix_predicate_eval(mix_predicate_t *pred, const mix_vm_t *vm) +{ +  g_return_val_if_fail (pred != NULL, FALSE); +  g_return_val_if_fail (vm != NULL, FALSE); +  return PRED_FUNCS_[pred->type] (pred, vm); +} + +/* change mem address of a MIX_PRED_MEM predicate */ +void +mix_predicate_set_mem_address (mix_predicate_t *predicate, +			       mix_address_t address) +{ +  g_return_if_fail (predicate != NULL); +  predicate->control = address; +} + +/* get message about predicate evaluation */ +const gchar * +mix_predicate_get_message (const mix_predicate_t *predicate) +{ +  enum {SIZE = 256}; +  static gchar BUFFER[SIZE]; +  static const gchar *CMP_STRINGS[] = { "L", "E", "G"}; +   +  g_return_val_if_fail (predicate != NULL, NULL); + +  switch (predicate->type) +    { +    case MIX_PRED_REG_A: +      snprintf (BUFFER, SIZE, "Register A changed to %s%d", +		mix_word_is_negative (predicate->data.regA)? "-" : "+", +		mix_word_magnitude (predicate->data.regA)); +      break; +    case MIX_PRED_REG_X: +      snprintf (BUFFER, SIZE, "Register X changed to %s%d", +		mix_word_is_negative (predicate->data.regX)? "-" : "+", +		mix_word_magnitude (predicate->data.regX)); +      break; +    case MIX_PRED_REG_J: +      snprintf (BUFFER, SIZE, "Register J changed to %d", +		mix_short_magnitude (predicate->data.regI)); +      break; +    case MIX_PRED_REG_I1: case MIX_PRED_REG_I2: case MIX_PRED_REG_I3: +    case MIX_PRED_REG_I4: case MIX_PRED_REG_I5: case MIX_PRED_REG_I6:  +      snprintf (BUFFER, SIZE, "Register I%d changed to %s%d", +		predicate->control, +		mix_short_is_negative (predicate->data.regI)? "-" : "+", +		mix_short_magnitude (predicate->data.regI)); +      break; +    case MIX_PRED_CMP: +      snprintf (BUFFER, SIZE, "Comparison flag changed to %s", +		CMP_STRINGS[predicate->data.cmp]); +      break; +    case MIX_PRED_OVER: +      snprintf (BUFFER, SIZE, "Overflow toggled %s", +		predicate->data.over ? "ON" : "OFF"); +      break; +    case MIX_PRED_MEM: +      snprintf (BUFFER, SIZE, "Memory address %d changed to %s%d", +		predicate->control, +		mix_word_is_negative (predicate->data.mem)? "-" : "+", +		mix_word_magnitude (predicate->data.mem)); +      break; +    default: +      g_assert_not_reached (); +    } +  return BUFFER; +} + diff --git a/mixlib/mix_predicate.h b/mixlib/mix_predicate.h new file mode 100644 index 0000000..df76afb --- /dev/null +++ b/mixlib/mix_predicate.h @@ -0,0 +1,75 @@ +/* -*-c-*- ---------------- mix_predicate.h : + * Predicates and lists of predicates testing vm status. + * ------------------------------------------------------------------ + *  Last change: Time-stamp: <2001-07-13 22:32:42 jao> + * ------------------------------------------------------------------ + * Copyright (C) 2001 Free Software Foundation, Inc. + *   + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + *   + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + *   + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *   + */ + + +#ifndef MIX_PREDICATE_H +#define MIX_PREDICATE_H + +#include "mix.h" +#include "mix_types.h" +#include "mix_ins.h" + +/* the predicate type */ +typedef struct mix_predicate_t mix_predicate_t; + +/* predicate types */ +typedef enum { +  MIX_PRED_REG_A, +  MIX_PRED_REG_X, +  MIX_PRED_REG_J, +  MIX_PRED_REG_I1, +  MIX_PRED_REG_I2, +  MIX_PRED_REG_I3, +  MIX_PRED_REG_I4, +  MIX_PRED_REG_I5, +  MIX_PRED_REG_I6, +  MIX_PRED_OVER, +  MIX_PRED_CMP, +  MIX_PRED_MEM +} mix_predicate_type_t; + +/* create predicates based on vm status */ +extern mix_predicate_t * +mix_predicate_new (mix_predicate_type_t type); + +/* delete a predicate */ +extern void +mix_predicate_delete (mix_predicate_t *predicate); + +/* change mem address of a MIX_PRED_MEM predicate */ +extern void +mix_predicate_set_mem_address (mix_predicate_t *predicate, +			       mix_address_t address); + +/* get message about predicate evaluation */ +extern const gchar * +mix_predicate_get_message (const mix_predicate_t *predicate); + +/* test a predicate */ +#include "mix_vm.h" + +extern gboolean +mix_predicate_eval(mix_predicate_t *pred, const mix_vm_t *vm); + +#endif /* MIX_PREDICATE_H */ + diff --git a/mixlib/mix_predicate_list.c b/mixlib/mix_predicate_list.c new file mode 100644 index 0000000..3e4fe08 --- /dev/null +++ b/mixlib/mix_predicate_list.c @@ -0,0 +1,111 @@ +/* -*-c-*- -------------- mix_predicate_list.c : + * Implementation of the functions declared in mix_predicate_list.h + * ------------------------------------------------------------------ + *  Last change: Time-stamp: "01/07/18 23:02:26 jao" + * ------------------------------------------------------------------ + * Copyright (C) 2001 Free Software Foundation, Inc. + *   + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + *   + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + *   + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *   + */ + + +#include "mix_predicate_list.h" + +/* the predicate list type */ +struct mix_predicate_list_t  +{ +  GSList *predicates; +  const mix_vm_t *vm; +  const mix_predicate_t *last; +}; + +/* a list of predicates */ +mix_predicate_list_t * +mix_predicate_list_new (const mix_vm_t *vm) +{ +  mix_predicate_list_t *result; +  g_return_val_if_fail (vm != NULL, NULL); +  result = g_new (mix_predicate_list_t, 1); +  result->predicates = NULL; +  result->vm = vm; +  result->last = NULL; +  return result; +} + +void +mix_predicate_list_delete (mix_predicate_list_t *list) +{ +  g_return_if_fail (list != NULL); +  g_slist_free (list->predicates); +  g_free (list); +} + +/* evaluate the predicate list */ +gboolean +mix_predicate_list_eval (mix_predicate_list_t *list) +{ +  GSList *node; +   +  g_return_val_if_fail (list != NULL, FALSE); +  node = list->predicates; +  while (node) { +    mix_predicate_t *pred = (mix_predicate_t *)(node->data); +    if (mix_predicate_eval (pred, list->vm)) +      { +	list->last = pred; +	return TRUE; +      } +    node = node->next; +  } +  list->last = NULL; +  return FALSE; +} + +/* add/remove predicates to the list */ +void +mix_predicate_list_add (mix_predicate_list_t *list, mix_predicate_t *predicate) +{ +  g_return_if_fail (list != NULL); +  g_return_if_fail (predicate != NULL); +  if (!g_slist_find (list->predicates, predicate)) +    list->predicates = g_slist_append (list->predicates, (gpointer)predicate); +  (void)mix_predicate_eval (predicate, list->vm); +} + +void +mix_predicate_list_remove (mix_predicate_list_t *list, +			   mix_predicate_t *predicate) +{ +  g_return_if_fail (list != NULL); +  g_return_if_fail (predicate != NULL); +  list->predicates = g_slist_remove (list->predicates, predicate); +} + +void +mix_predicate_list_clear (mix_predicate_list_t *list) +{ +  g_return_if_fail (list != NULL); +  g_slist_free (list->predicates); +  list->predicates = NULL; +  list->last = NULL; +} + +const mix_predicate_t * +mix_predicate_list_last_true_eval (const mix_predicate_list_t *list) +{ +  g_return_val_if_fail (list != NULL, NULL); +  return list->last; +} diff --git a/mixlib/mix_predicate_list.h b/mixlib/mix_predicate_list.h new file mode 100644 index 0000000..416f3db --- /dev/null +++ b/mixlib/mix_predicate_list.h @@ -0,0 +1,61 @@ +/* -*-c-*- ---------------- mix_predicate_list.h : + * A list of predicates. + * ------------------------------------------------------------------ + *  Last change: Time-stamp: <01/07/18 23:02:40 jao> + * ------------------------------------------------------------------ + * Copyright (C) 2001 Free Software Foundation, Inc. + *   + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + *   + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + *   + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *   + */ + + +#ifndef MIX_PREDICATE_LIST_H +#define MIX_PREDICATE_LIST_H + +#include "mix.h" +#include "mix_vm.h" +#include "mix_predicate.h" + +/* the predicate list type */ +typedef struct mix_predicate_list_t mix_predicate_list_t; + +/* create/destroy a list of predicates */ +extern mix_predicate_list_t * +mix_predicate_list_new (const mix_vm_t *vm); + +extern void +mix_predicate_list_delete (mix_predicate_list_t *list); + +/* evaluate the predicate list */ +extern gboolean +mix_predicate_list_eval (mix_predicate_list_t *list); + +extern const mix_predicate_t * +mix_predicate_list_last_true_eval (const mix_predicate_list_t *list); + +/* add/remove predicates to the list */ +extern void +mix_predicate_list_add (mix_predicate_list_t *list, mix_predicate_t *predicate); + +extern void +mix_predicate_list_remove (mix_predicate_list_t *list, +			   mix_predicate_t *predicate); + +extern void +mix_predicate_list_clear (mix_predicate_list_t *list); + +#endif /* MIX_PREDICATE_LIST_H */ + diff --git a/mixlib/mix_vm.c b/mixlib/mix_vm.c index f41c60a..8929527 100644 --- a/mixlib/mix_vm.c +++ b/mixlib/mix_vm.c @@ -65,7 +65,8 @@ vm_reset_reload_ (mix_vm_t *vm, gboolean is_reload)  	mix_device_delete (vm->devices[k]);  	vm->devices[k] = NULL;        } -  if (!is_reload) bp_clear_all_ (vm); +  if (!is_reload) +    mix_vm_clear_all_breakpoints (vm);  } @@ -80,6 +81,7 @@ mix_vm_new (void)    vm->address_table = NULL;    vm->symbol_table = NULL;    vm->src_file = NULL; +  vm->pred_list = mix_predicate_list_new (vm);    for (i = 0; i < BD_NO_; ++i)      vm->devices[i] = NULL; @@ -451,6 +453,8 @@ mix_vm_run (mix_vm_t *vm)  	update_time_ (vm, &ins);        if (bp_is_set_ (vm, get_loc_ (vm)))  	return MIX_VM_BREAK; +      if (mix_predicate_list_eval (get_pred_list_ (vm))) +	return MIX_VM_COND_BREAK;        if (get_loc_ (vm) >= MIX_VM_CELL_NO) halt_ (vm, TRUE);      }    return MIX_VM_HALT; @@ -470,7 +474,10 @@ mix_vm_exec_next (mix_vm_t *vm)    else      update_time_ (vm, &ins);    if (is_halted_ (vm)) return MIX_VM_HALT; -  return bp_is_set_ (vm, get_loc_ (vm)) ? MIX_VM_BREAK : MIX_VM_OK; +  if (bp_is_set_ (vm, get_loc_ (vm))) return MIX_VM_BREAK; +  if (mix_predicate_list_eval (get_pred_list_ (vm))) +    return MIX_VM_COND_BREAK; +  return MIX_VM_OK;  }  /* Breakpoints */ @@ -590,6 +597,36 @@ mix_vm_clear_all_breakpoints (mix_vm_t *vm)  {    g_return_if_fail (vm != NULL);    bp_clear_all_ (vm); +  mix_predicate_list_clear (get_pred_list_ (vm)); +} + + +gint +mix_vm_set_conditional_breakpoint (mix_vm_t *vm, mix_predicate_t *pred) +{ +  g_return_val_if_fail (vm != NULL, MIX_VM_BP_ERROR); +  g_return_val_if_fail (pred != NULL, MIX_VM_BP_ERROR); +  mix_predicate_list_add (get_pred_list_ (vm), pred); +  return MIX_VM_BP_OK; +} + +gint +mix_vm_clear_conditional_breakpoint (mix_vm_t *vm, mix_predicate_t *pred) +{ +  g_return_val_if_fail (vm != NULL, MIX_VM_BP_ERROR); +  g_return_val_if_fail (pred != NULL, MIX_VM_BP_ERROR); +  mix_predicate_list_remove (get_pred_list_ (vm), pred); +  return MIX_VM_BP_OK; +} + +const gchar * +mix_vm_get_last_breakpoint_message (const mix_vm_t *vm) +{ +  const mix_predicate_t *last = NULL; +  g_return_val_if_fail (vm != NULL, NULL); +  if ((last = mix_predicate_list_last_true_eval (get_pred_list_ (vm))) != NULL) +    return mix_predicate_get_message (last); +  return NULL;  }  /* Get the vm uptime, defined as the time spent executing instructions */ diff --git a/mixlib/mix_vm.h b/mixlib/mix_vm.h index a8b826e..663062b 100644 --- a/mixlib/mix_vm.h +++ b/mixlib/mix_vm.h @@ -162,6 +162,7 @@ mix_vm_reset_program (mix_vm_t *vm);  enum {    MIX_VM_ERROR,		/* error executing instructions */    MIX_VM_BREAK,		/* breakpoint found */ +  MIX_VM_COND_BREAK,    /* conditional breakpoint found */    MIX_VM_HALT,		/* end of execution */    MIX_VM_OK		/* successful instruction execution */  }; @@ -205,6 +206,16 @@ mix_vm_has_breakpoint_at_address (const mix_vm_t *vm, guint address);  extern void  mix_vm_clear_all_breakpoints (mix_vm_t *vm); +#include "mix_predicate.h" +extern gint +mix_vm_set_conditional_breakpoint (mix_vm_t *vm, mix_predicate_t *pred); + +extern gint +mix_vm_clear_conditional_breakpoint (mix_vm_t *vm, mix_predicate_t *pred); + +extern const gchar * +mix_vm_get_last_breakpoint_message (const mix_vm_t *vm); +  /* Get the vm uptime, defined as the time spent executing instructions */  extern mix_time_t  mix_vm_get_uptime (const mix_vm_t *vm); diff --git a/mixlib/mix_vm_command.c b/mixlib/mix_vm_command.c index bb4b67f..9344618 100644 --- a/mixlib/mix_vm_command.c +++ b/mixlib/mix_vm_command.c @@ -37,6 +37,9 @@  #  include <readline/history.h>  #endif +#ifdef HAVE_LIBREADLINE +#  include <readline/readline.h> +#endif  /* hooks */  typedef struct  @@ -268,14 +271,14 @@ mix_vm_cmd_dispatcher_new_with_config (FILE *out, FILE *err,        val = mix_config_get (result->config, TIMING_KEY_);        if (val) cmd_timing_ (result, val);        val = mix_config_get_devices_dir (result->config); -      if (!val) +      if (!val || !mix_stat_dir (val, "devices"))  	{  	  gchar *dirname = g_dirname (mix_config_get_filename (config));  	  cmd_devdir_ (result, dirname);  	  g_free (dirname);  	}        else -	cmd_devdir_ (result, val); +	mix_device_set_dir (val);  #ifdef HAVE_LIBHISTORY        val = mix_config_get_history_file (result->config);        hsize = mix_config_get_history_size (result->config); @@ -361,7 +364,7 @@ mix_vm_cmd_dispatcher_get_src_file_path (const mix_vm_cmd_dispatcher_t *dis)        g_free (PATH);        PATH = NULL;      } -     +    if (f)      PATH = mix_file_complete_name (mix_src_file_get_path (f), MIX_SRC_DEFEXT); diff --git a/mixlib/xmix_vm.h b/mixlib/xmix_vm.h index d5cbff4..4ed1e42 100644 --- a/mixlib/xmix_vm.h +++ b/mixlib/xmix_vm.h @@ -29,6 +29,7 @@  #include "mix_symbol_table.h"  #include "mix_device.h"  #include "mix_src_file.h" +#include "mix_predicate_list.h"  #include "mix_vm.h"  /* The mix_vm_t type */ @@ -50,6 +51,7 @@ struct mix_vm_t    mix_symbol_table_t *symbol_table;    mix_src_file_t *src_file;	/* source of last loaded code file */    mix_device_factory_t factory; /* the factory for new devices */ +  mix_predicate_list_t *pred_list; /* predicates for conditional bps */  };  /* Macros for accessing/modifying the above structure. @@ -72,6 +74,7 @@ enum { A_ = 0, X_, J_, I1_, I2_, I3_, I4_, I5_, I6_ };  #define get_over_(vm) (vm->overflow)  #define get_loc_(vm)  (vm->loc_count)  #define get_clock_(vm) (vm->clock) +#define get_pred_list_(vm) (vm->pred_list)  #define set_reg_(vm,r,x)			\  do {						\  | 
