This documents the design of structure checking within the MPS.
.hist.0: Incomplete design. Gavin Matthews, 1996-08-05.
.hist.1: Converted from MMInfo database design document. Richard Brooksby, 2002-06-07.
.hist.2: Converted to reStructuredText. Gareth Rees, 2013-03-12.
.level: There are three levels of checking:
.level.control: Control over the levels of checking is via the definition of at most one of the macros TARGET_CHECK_SHALLOW (which if defined gives .level.shallow), TARGET_CHECK_DEEP (which if defined gives .level.deep). If neither macro is defined then .level.sig is used. These macros are not intended to be manipulated directly by developers, they should use the interface in impl.h.target.
.order: Because deep checking (.level.deep) uses unchecked recursion, it is important that child relationships are acyclic (.macro.down).
.fun: Every abstract data type which is a structure pointer should have a function <type>Check which takes a pointer of type <type> and returns a Bool. It should check all fields in order, using one of the macros in .macro, or document why not.
.fun.omit: The only fields which should be omitted from a check function are those for which there is no meaningful check (for example, an unlimited unsigned integer with no relation to other fields).
.fun.return: Although the function returns a Bool, if the assert handler returns (or there is no assert handler), then this is taken to mean “ignore and continue”, and the check function hence returns TRUE.
.macro: Checking is implemented by invoking four macros in impl.h.assert:
.full-type: CHECKS, CHECKD, CHECKU, all operate only on fully fledged types. This means the type has to provide a function Bool TypeCheck(Type type) where Type is substituted for the name of the type (for example, PoolCheck()), and the expression obj->sig must be a valid value of type Sig whenever obj is a valid value of type Type.
.type.no-sig: This tag is to be referenced in implementations whenever the form CHECKL(ThingCheck(thing)) is used instead of CHECK{U,D}(Thing, thing) because Thing is not a fully fledged type (.full-type).