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:
parent
f21d24ee6c
commit
bb5a36b27e
4 changed files with 45 additions and 33 deletions
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue