Files
mercury/runtime/mercury_overflow.h
Mark Brown d465fa53cb Update the COPYING.LIB file and references to it.
Discussion of these changes can be found on the Mercury developers
mailing list archives from June 2018.

COPYING.LIB:
    Add a special linking exception to the LGPL.

*:
    Update references to COPYING.LIB.

    Clean up some minor errors that have accumulated in copyright
    messages.
2018-06-09 17:43:12 +10:00

138 lines
6.5 KiB
C

// vim: ts=4 sw=4 expandtab ft=c
// Copyright (C) 1995-1998,2000-2001, 2005-2006 The University of Melbourne.
// Copyright (C) 2014, 2016, 2018 The Mercury team.
// This file is distributed under the terms specified in COPYING.LIB.
// 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.
#if !defined(MR_HIGHLEVEL_CODE)
extern void MR_nondetstack_inclusion_check(MR_Word *maxfr,
const char *error, const char *where);
#endif
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