/* ** vim: ts=4 sw=4 expandtab */ /* ** Copyright (C) 1995-1998,2000-2001, 2005-2006 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. */ /* mercury_overflow.h - definitions for overflow checks */ #ifndef MERCURY_OVERFLOW_H #define MERCURY_OVERFLOW_H #include "mercury_types.h" #include "mercury_memory_zones.h" /* ** If maxfr is not in any of the zones of the nondet stack, abort the program, ** with the abort message including the message in `error', and (if not NULL) ** the location in `where'. ** ** If maxfr *is* in one of the zones of the nondet stack, then update ** its MR_zone_max field if maxfr exceeds it, since the MR_zone_max field ** should always hold the highest address used in the zone so far. */ extern void MR_nondetstack_inclusion_check(MR_Word *maxfr, const char *error, const char *where); typedef enum { MR_OVERFLOW_ZONE_DETSTACK, MR_OVERFLOW_ZONE_NONDETSTACK, MR_OVERFLOW_ZONE_HEAP, MR_OVERFLOW_ZONE_OTHER } MR_OverflowZone; /* ** Output a message about a zone error to standard error and abort. ** This function is for fatal zone underflow and overflow errors ** in the Mercury runtime. */ MR_NO_RETURN(extern void \ MR_fatal_zone_error(MR_OverflowZone ptr_kind, const char *ptr_name, const void *ptr, const char *zone_name, const MR_MemoryZone *zone, const MR_MemoryZones *zones, const char *error, const char *where)); #ifndef MR_CHECK_FOR_OVERFLOW #define MR_heap_overflow_check() ((void) 0) #define MR_detstack_overflow_check() ((void) 0) #define MR_detstack_overflow_check_msg(x) ((void) 0) #define MR_detstack_underflow_check() ((void) 0) #define MR_detstack_underflow_check_msg(x) ((void) 0) #define MR_nondetstack_overflow_check() ((void) 0) #define MR_nondetstack_overflow_check_msg(x) ((void) 0) #define MR_nondetstack_underflow_check() ((void) 0) #define MR_nondetstack_underflow_check_msg(x) ((void) 0) #else /* MR_CHECK_FOR_OVERFLOW */ #include "mercury_regs.h" #include "mercury_misc.h" /* for MR_fatal_error() */ #define MR_heap_overflow_check() \ ( \ MR_IF (MR_hp >= MR_ENGINE(MR_eng_heap_zone)->MR_zone_top,( \ MR_fatal_error("heap overflow") \ )), \ MR_IF (MR_hp > MR_ENGINE(MR_eng_heap_zone)->MR_zone_max,( \ MR_ENGINE(MR_eng_heap_zone)->MR_zone_max = MR_hp \ )), \ (void)0 \ ) #define MR_detstack_overflow_check() \ ( \ MR_IF (MR_sp >= MR_CONTEXT(MR_ctxt_detstack_zone)->MR_zone_top,( \ MR_fatal_error("stack overflow") \ )), \ MR_IF (MR_sp > MR_CONTEXT(MR_ctxt_detstack_zone)->MR_zone_max,( \ MR_CONTEXT(MR_ctxt_detstack_zone)->MR_zone_max = MR_sp \ )), \ (void)0 \ ) #define MR_detstack_overflow_check_msg(where) \ ( \ MR_IF (MR_sp >= MR_CONTEXT(MR_ctxt_detstack_zone)->MR_zone_top,( \ MR_fatal_error("stack overflow: " where) \ )), \ MR_IF (MR_sp > MR_CONTEXT(MR_ctxt_detstack_zone)->MR_zone_max,( \ MR_CONTEXT(MR_ctxt_detstack_zone)->MR_zone_max = MR_sp \ )), \ (void)0 \ ) #define MR_detstack_underflow_check() \ ( \ MR_IF (MR_sp < MR_CONTEXT(MR_ctxt_detstack_zone)->MR_zone_min,( \ MR_fatal_error("stack underflow") \ )), \ (void)0 \ ) #define MR_detstack_underflow_check_msg(where) \ ( \ MR_IF (MR_sp < MR_CONTEXT(MR_ctxt_detstack_zone)->MR_zone_min,( \ MR_fatal_error("stack underflow: " where) \ )), \ (void)0 \ ) /* ** Checking for overflow and underflow on the nondet stack is not as simple ** as on the det stack. Since it is OK for MR_maxfr to be in a segment that ** is NOT currently the top nondet stack segment (see the comment on ** MR_new_nondetstack_segment to see why), we have check whether MR_maxfr ** is in *any* of the segments that currently belong to the nondet stack. ** ** MR_nondetstack_inclusion_check will set the MR_zone_max field of a zone ** if MR_maxfr exceeds it. It will test for this even during underflow checks, ** since testing whether the current check is for underflow would probably ** take just as long. */ #define MR_nondetstack_overflow_check() \ MR_nondetstack_inclusion_check(MR_maxfr, "nondetstack overflow", NULL) #define MR_nondetstack_overflow_check_msg(where) \ MR_nondetstack_inclusion_check(MR_maxfr, "nondetstack overflow", where) #define MR_nondetstack_underflow_check() \ MR_nondetstack_inclusion_check(MR_maxfr, "nondetstack underflow", NULL) #define MR_nondetstack_underflow_check_msg(where) \ MR_nondetstack_inclusion_check(MR_maxfr, "nondetstack underflow", where) #endif /* MR_CHECK_FOR_OVERFLOW */ #endif /* not MERCURY_OVERFLOW_H */