mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-30 04:10:54 -08:00
Implementing mustbea_critical and elision of mustbea assertions in different varieties.
Copied from Perforce Change: 190925 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
690df6974a
commit
aa4036fbfd
4 changed files with 46 additions and 20 deletions
|
|
@ -56,6 +56,10 @@
|
|||
mps_lib_assert_fail(MPS_FILE, __LINE__, (condstring)); \
|
||||
END
|
||||
|
||||
#define ASSERTP(cond, condstring, dflt) \
|
||||
((cond) ? (dflt) : \
|
||||
mps_lib_assert_fail_expr(MPS_FILE, __LINE__, condstring, dflt))
|
||||
|
||||
#define ASSERT_ISTYPE(type, val) (type ## Check(val))
|
||||
#define ASSERT_TYPECHECK(type, val) \
|
||||
ASSERT(ASSERT_ISTYPE(type, val), "TypeCheck " #type ": " #val)
|
||||
|
|
@ -109,17 +113,27 @@ extern unsigned CheckLevel;
|
|||
#endif
|
||||
|
||||
|
||||
/* AVER, AVERT -- MPM assertions
|
||||
/* AVER, AVERT, AVERC, AVERP -- MPM assertions
|
||||
*
|
||||
* AVER and AVERT are used to assert conditions in the code. AVER checks
|
||||
* an expression. AVERT checks that a value is of the correct type and
|
||||
* may perform consistency checks on the value.
|
||||
* AVER and friends are used to assert conditions in the code.
|
||||
*
|
||||
* AVER and AVERT are on by default, and check conditions even in "hot"
|
||||
* varieties intended to work in production. To avoid the cost of a check
|
||||
* in critical parts of the code, use AVER_CRITICAL and AVERT_CRITICAL,
|
||||
* but only when you've *proved* that this makes a difference to performance
|
||||
* that affects requirements.
|
||||
* AVER checks an expression.
|
||||
*
|
||||
* AVERT checks that a value is of the correct type and may perform
|
||||
* consistency checks on the value by calling a check function.
|
||||
*
|
||||
* AVERC checks that a value is of the correct class (including
|
||||
* subclasses) and may perform consistency checks on the value by
|
||||
* calling a check function.
|
||||
*
|
||||
* AVERP checks an expression but is itself a void * expression, and
|
||||
* so can be used in expression macros.
|
||||
*
|
||||
* AVER etc. are on by default, and check conditions even in "hot"
|
||||
* varieties intended to work in production. To avoid the cost of a
|
||||
* check in critical parts of the code, use AVER_CRITICAL etc., but
|
||||
* only when you've *proved* that this makes a difference to
|
||||
* performance that affects requirements.
|
||||
*/
|
||||
|
||||
#if defined(AVER_AND_CHECK_NONE)
|
||||
|
|
@ -127,12 +141,14 @@ extern unsigned CheckLevel;
|
|||
#define AVER(cond) DISCARD(cond)
|
||||
#define AVERT(type, val) DISCARD(ASSERT_ISTYPE(type, val))
|
||||
#define AVERC(class, val) DISCARD(ASSERT_ISCLASS(class, val))
|
||||
#define AVERP(cond, dflt) (DISCARD_EXP(cond), dflt)
|
||||
|
||||
#else
|
||||
|
||||
#define AVER(cond) ASSERT(cond, #cond)
|
||||
#define AVERT ASSERT_TYPECHECK
|
||||
#define AVERC ASSERT_CLASSCHECK
|
||||
#define AVERP(cond, dflt) ASSERTP(cond, #cond, dflt)
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -141,12 +157,14 @@ extern unsigned CheckLevel;
|
|||
#define AVER_CRITICAL(cond) ASSERT(cond, #cond)
|
||||
#define AVERT_CRITICAL ASSERT_TYPECHECK
|
||||
#define AVERC_CRITICAL ASSERT_CLASSCHECK
|
||||
#define AVERP_CRITICAL(cond, dflt) ASSERTP(cond, #cond, dflt)
|
||||
|
||||
#else
|
||||
|
||||
#define AVER_CRITICAL DISCARD
|
||||
#define AVERT_CRITICAL(type, val) DISCARD(ASSERT_ISTYPE(type, val))
|
||||
#define AVERC_CRITICAL(class, val) DISCARD(ASSERT_ISCLASS(class, val))
|
||||
#define AVERP_CRITICAL(cond, dflt) (DISCARD_EXP(cond), dflt)
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -125,6 +125,15 @@ typedef const struct SrcIdStruct {
|
|||
END
|
||||
|
||||
|
||||
/* DISCARD_EXP -- discard an expression, as an expression
|
||||
*
|
||||
* Like DISCARD, except that it is itself an expression yielding zero
|
||||
* (the most ambiguous expression).
|
||||
*/
|
||||
|
||||
#define DISCARD_EXP(expr) (sizeof((expr)!=0), 0)
|
||||
|
||||
|
||||
/* DISCARD_STAT -- discards a statement, but checks syntax
|
||||
*
|
||||
* The argument is a statement; the expansion followed by a semicolon
|
||||
|
|
|
|||
|
|
@ -1534,7 +1534,7 @@ static Res AMCFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
|
|||
return ResOK;
|
||||
}
|
||||
|
||||
amc = MustBeA(AMCZPool, pool); /* FIXME: CRITICAL */
|
||||
amc = MustBeA_CRITICAL(AMCZPool, pool);
|
||||
AVERT_CRITICAL(AMC, amc);
|
||||
format = pool->format;
|
||||
headerSize = format->headerSize;
|
||||
|
|
@ -1745,7 +1745,7 @@ static void amcReclaimNailed(Pool pool, Trace trace, Seg seg)
|
|||
*/
|
||||
static void AMCReclaim(Pool pool, Trace trace, Seg seg)
|
||||
{
|
||||
AMC amc = MustBeA(AMCZPool, pool); /* FIXME: CRITICAL */
|
||||
AMC amc = MustBeA_CRITICAL(AMCZPool, pool);
|
||||
amcGen gen;
|
||||
|
||||
AVERT_CRITICAL(Trace, trace);
|
||||
|
|
|
|||
|
|
@ -206,9 +206,6 @@ extern void InstFinish(Inst inst);
|
|||
|
||||
|
||||
/* IsA, CouldBeA, MustBeA -- coerce instances safely
|
||||
*
|
||||
* FIXME: Enumerate TypeIds to avoid call to ensure method and
|
||||
* subclass test.
|
||||
*
|
||||
* FIXME: Wrap mps_lib_assert_fail_expr in check.h so that it is
|
||||
* elided from some varieties.
|
||||
|
|
@ -222,14 +219,16 @@ extern void InstFinish(Inst inst);
|
|||
#define IsA(_class, inst) \
|
||||
IsSubclass(CouldBeA(Inst, inst)->class, _class)
|
||||
|
||||
#define MustBeA(_class, inst) \
|
||||
#define IsNonNullAndA(_class, inst) \
|
||||
((inst) != NULL && \
|
||||
CouldBeA(Inst, inst)->class != NULL && \
|
||||
IsA(_class, inst) ? \
|
||||
CouldBeA(_class, inst) : \
|
||||
CouldBeA(_class, mps_lib_assert_fail_expr(MPS_FILE, __LINE__, \
|
||||
"MustBeA " #_class ": " #inst, \
|
||||
inst)))
|
||||
IsA(_class, inst))
|
||||
|
||||
#define MustBeA(_class, inst) \
|
||||
CouldBeA(_class, AVERP(IsNonNullAndA(_class, inst), inst))
|
||||
|
||||
#define MustBeA_CRITICAL(_class, inst) \
|
||||
CouldBeA(_class, AVERP_CRITICAL(IsNonNullAndA(_class, inst), inst))
|
||||
|
||||
/* ClassOf* -- get the class of an instance */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue