1
Fork 0
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:
Richard Brooksby 2016-04-11 16:09:29 +01:00
parent 690df6974a
commit aa4036fbfd
4 changed files with 46 additions and 20 deletions

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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 */