1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-04-27 16:51:06 -07:00

Using the address of the class as its id as a step to eliminating classdef.h.

Copied from Perforce
 Change: 191234
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Richard Brooksby 2016-04-19 14:21:29 +01:00
parent f21d24ee6c
commit bb5a36b27e
4 changed files with 45 additions and 33 deletions

View file

@ -52,12 +52,12 @@
#define ASSERT(cond, condstring) \
BEGIN \
if (cond) NOOP; else \
if (LIKELY(cond)) NOOP; else \
mps_lib_assert_fail(MPS_FILE, __LINE__, (condstring)); \
END
#define ASSERTP(cond, condstring, dflt) \
((cond) ? (dflt) : \
(LIKELY(cond) ? (dflt) : \
mps_lib_assert_fail_expr(MPS_FILE, __LINE__, condstring, dflt))
#define ASSERT_ISTYPE(type, val) (type ## Check(val))

View file

@ -304,6 +304,22 @@
#endif
/* Compiler extensions */
/* LIKELY -- likely conditions
*
* Use to annotate conditions that are likely to be true, such as
* assertions, to help move unlikely code out-of-line. See
* <https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html>.
*/
#if defined(MPS_BUILD_GC) || defined(MPS_BUILD_LL)
#define LIKELY(exp) __builtin_expect((exp) != 0, 1)
#else
#define LIKELY(exp) ((exp) != 0)
#endif
/* EPVMDefaultSubsequentSegSIZE is a default for the alignment of
* subsequent segments (non-initial at each save level) in EPVM. See
* design.mps.poolepvm.arch.segment.size.

View file

@ -34,7 +34,7 @@ DEFINE_CLASS(Inst, InstClass, class)
class->superclass = &CLASS_STATIC(Inst);
class->name = "InstClass";
class->level = ClassLevelInstClass;
class->display[ClassLevelInstClass] = ClassIdInstClass;
class->display[ClassLevelInstClass] = CLASS_ID(InstClass);
}
static void InstClassInitInternal(InstClass class)
@ -44,9 +44,9 @@ static void InstClassInitInternal(InstClass class)
class->name = "Inst";
class->superclass = NULL;
for (i = 0; i < ClassDEPTH; ++i)
class->display[i] = 0;
class->display[i] = NULL;
class->level = 0;
class->display[class->level] = ClassIdInst;
class->display[class->level] = CLASS_ID(Inst);
/* We can't call CLASS(InstClass) here because it causes a loop back
to here, so we have to tie this knot specially. */
@ -66,11 +66,10 @@ Bool InstClassCheck(InstClass class)
CHECKL(class->name != NULL);
CHECKL(class->level < ClassDEPTH);
for (i = 0; i <= class->level; ++i) {
CHECKL(class->display[i] != 0);
CHECKL(class->display[i] < ClassIdLIMIT);
CHECKL(class->display[i] != NULL);
}
for (i = class->level + 1; i < ClassDEPTH; ++i) {
CHECKL(class->display[i] == 0);
CHECKL(class->display[i] == NULL);
}
return TRUE;
}
@ -102,8 +101,8 @@ static InstClassStruct invalidClassStruct = {
/* .sig = */ SigInvalid,
/* .name = */ "Invalid",
/* .superclass = */ &invalidClassStruct,
/* .level = */ ClassIdInvalid,
/* .display = */ {ClassIdInvalid}
/* .level = */ 0,
/* .display = */ {(ClassId)&invalidClassStruct}
};
void InstFinish(Inst inst)

View file

@ -71,6 +71,18 @@
#define KIND_CLASS(ident) ident ## Class
/* ClassId -- static identity of a class
*
* We use the address of the static storage for the canonical class
* object as the class id, suitable for fast comparison. This is not
* intended to be dereferences, so it's defined as a pointer to an
* incomplete structure.
*/
typedef struct ClassIdStruct *ClassId;
#define CLASS_ID(ident) ((ClassId)&CLASS_STATIC(ident))
/* DECLARE_CLASS -- declare the existence of a protocol class
*
* Declares a prototype for the class ensure function, which ensures
@ -80,7 +92,8 @@
#define DECLARE_CLASS(kind, ident) \
extern CLASS_TYPE(kind) CLASS_ENSURE(ident)(void); \
extern void CLASS_INIT(ident)(CLASS_TYPE(kind) var)
extern void CLASS_INIT(ident)(CLASS_TYPE(kind) var); \
extern CLASS_STRUCT(kind) CLASS_STATIC(ident)
/* DEFINE_CLASS -- define a protocol class
@ -95,7 +108,7 @@
#define DEFINE_CLASS(kind, ident, var) \
DECLARE_CLASS(kind, ident); \
static Bool CLASS_GUARDIAN(ident) = FALSE; \
static CLASS_STRUCT(kind) CLASS_STATIC(ident); \
CLASS_STRUCT(kind) CLASS_STATIC(ident); \
CLASS_TYPE(kind) CLASS_ENSURE(ident)(void) \
{ \
CLASS_TYPE(kind) class = &CLASS_STATIC(ident); \
@ -104,8 +117,8 @@
if (CLASS_GUARDIAN(ident) == FALSE) { \
CLASS_INIT(ident)(class); \
/* Prevent infinite regress. */ \
if (ClassId ## ident != ClassIdInstClass && \
ClassId ## ident != ClassIdInst) \
if (CLASS_ID(ident) != CLASS_ID(InstClass) && \
CLASS_ID(ident) != CLASS_ID(Inst)) \
SetClassOfPoly(class, CLASS(KIND_CLASS(kind))); \
AVER(CLASS_CHECK(kind)(class)); \
CLASS_GUARDIAN(ident) = TRUE; \
@ -127,21 +140,6 @@
#define CLASS(ident) (CLASS_ENSURE(ident)())
/* ClassIdEnum -- unique identifier for each class
*
* This defines enum constants like ClassIdLand with a unique small
* number for each class -- essentially the row number in the class
* table. Used to implement design.mps.protocol.impl.subclass.
*/
#define CLASS_ID_ENUM(prefix, ident, kind, super) prefix ## ident,
typedef enum ClassIdEnum {
ClassIdInvalid, /* index zero reserved for invalid classes */
CLASSES(CLASS_ID_ENUM, ClassId)
ClassIdLIMIT
} ClassIdEnum;
/* ClassLevelEnum -- depth of class in hierarchy
*
* This defines enum constants like ClassLevelLand equal to the
@ -173,7 +171,7 @@ typedef enum ClassLevelEnum {
instClass->name = #_class; \
instClass->level = instClass->superclass->level + 1; \
AVER(instClass->level < ClassDEPTH); \
instClass->display[instClass->level] = ClassId ## _class; \
instClass->display[instClass->level] = CLASS_ID(_class); \
END
@ -193,7 +191,6 @@ typedef struct InstStruct {
} InstStruct;
typedef const char *ClassName;
typedef unsigned char ClassId;
typedef unsigned char ClassLevel;
#define ClassDEPTH 8 /* maximum depth of class hierarchy */
@ -205,7 +202,7 @@ typedef struct InstClassStruct {
ClassName name; /* human readable name such as "Land" */
InstClass superclass; /* pointer to direct superclass */
ClassLevel level; /* distance from root of class hierarchy */
ClassId display[ClassDEPTH]; /* ids of classes at this level and above */
ClassId display[ClassDEPTH]; /* classes at this level and above */
} InstClassStruct;
DECLARE_CLASS(Inst, InstClass);
@ -235,7 +232,7 @@ extern void ClassRegister(InstClass class);
*/
#define IsSubclass(sub, super) \
(((InstClass)(sub))->display[ClassLevel ## super] == ClassId ## super)
(((InstClass)(sub))->display[ClassLevel ## super] == CLASS_ID(super))
#define IsA(_class, inst) \
IsSubclass(CouldBeA(Inst, inst)->class, _class)