/* Fundamental definitions for GNU Emacs Lisp interpreter.
- Copyright (C) 1985,86,87,93,94,95,97,98,1999,2000, 2001, 2002, 2003
+ Copyright (C) 1985,86,87,93,94,95,97,98,1999,2000,01,02,03,2004
Free Software Foundation, Inc.
This file is part of GNU Emacs.
? (void) 0 \
: die ((msg), __FILE__, __LINE__)), \
0)
-
-/* Let's get some compile-time checking too. */
-#undef NO_UNION_TYPE
-
#else
/* Produce same side effects and result, but don't complain. */
/* For convenience, we also store the number of elements in these bits. */
#define PSEUDOVECTOR_SIZE_MASK 0x1ff
+\f
+/***** Select the tagging scheme. *****/
+
+/* First, try and define DECL_ALIGN(type,var) which declares a static
+ variable VAR of type TYPE with the added requirement that it be
+ TYPEBITS-aligned. */
+#if defined USE_LSB_TAG && !defined DECL_ALIGN
+/* What compiler directive should we use for non-gcc compilers? -stef */
+# if defined (__GNUC__)
+# define DECL_ALIGN(type, var) \
+ type __attribute__ ((__aligned__ (1 << GCTYPEBITS))) var
+# else
+# error "USE_LSB_TAG used without defining DECL_ALIGN"
+# endif
+#endif
+
+#ifndef USE_LSB_TAG
+/* Just remove the alignment annotation if we don't use it. */
+#undef DECL_ALIGN
+#define DECL_ALIGN(type, var) type var
+#endif
+
\f
/* These macros extract various sorts of values from a Lisp_Object.
For example, if tem is a Lisp_Object whose type is Lisp_Cons,
#ifdef NO_UNION_TYPE
+#ifdef USE_LSB_TAG
+
+#define TYPEMASK ((((EMACS_INT) 1) << GCTYPEBITS) - 1)
+#define XTYPE(a) ((enum Lisp_Type) (((EMACS_UINT) (a)) & TYPEMASK))
+#define XINT(a) (((EMACS_INT) (a)) >> GCTYPEBITS)
+#define XUINT(a) (((EMACS_UINT) (a)) >> GCTYPEBITS)
+#define XSET(var, type, ptr) \
+ (eassert (XTYPE (ptr) == 0), /* Check alignment. */ \
+ (var) = ((EMACS_INT) (type)) | ((EMACS_INT) (ptr)))
+#define make_number(N) (((EMACS_INT) (N)) << GCTYPEBITS)
+
+/* XFASTINT and XSETFASTINT are for use when the integer is known to be
+ positive, in which case the implementation can sometimes be faster
+ depending on the tagging scheme. With USE_LSB_TAG, there's no benefit. */
+#define XFASTINT(a) XINT (a)
+#define XSETFASTINT(a, b) ((a) = make_number (b))
+
+#define XPNTR(a) ((EMACS_INT) ((a) & ~TYPEMASK))
+
+#else /* not USE_LSB_TAG */
+
#define VALMASK ((((EMACS_INT) 1) << VALBITS) - 1)
/* One need to override this if there must be high bits set in data space
#define make_number(N) \
((((EMACS_INT) (N)) & VALMASK) | ((EMACS_INT) Lisp_Int) << VALBITS)
+#endif /* not USE_LSB_TAG */
+
#define EQ(x, y) ((x) == (y))
#else /* not NO_UNION_TYPE */
unsigned gcmarkbit : 1;
int spacer : 15;
union Lisp_Misc *chain;
+#ifdef USE_LSB_TAG
+ /* Try to make sure that sizeof(Lisp_Misc) preserves TYPEBITS-alignment.
+ This assumes that Lisp_Marker is the largest of the alternatives and
+ that Lisp_Intfwd has the same size as "Lisp_Free w/o padding". */
+ char padding[((((sizeof (struct Lisp_Marker) - 1) >> GCTYPEBITS) + 1)
+ << GCTYPEBITS) - sizeof (struct Lisp_Intfwd)];
+#endif
};
/* To get the type field of a union Lisp_Misc, use XMISCTYPE.
#define DEFUN(lname, fnname, sname, minargs, maxargs, prompt, doc) \
Lisp_Object fnname (); \
- struct Lisp_Subr sname = \
+ DECL_ALIGN (struct Lisp_Subr, sname) = \
{ PVEC_SUBR | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)), \
fnname, minargs, maxargs, lname, prompt, 0}; \
Lisp_Object fnname
arguments, so we can catch errors with maxargs at compile-time. */
#define DEFUN(lname, fnname, sname, minargs, maxargs, prompt, doc) \
Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \
- struct Lisp_Subr sname = \
+ DECL_ALIGN (struct Lisp_Subr, sname) = \
{ PVEC_SUBR | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)), \
fnname, minargs, maxargs, lname, prompt, 0}; \
Lisp_Object fnname
This is a good thing to do around a loop that has no side effects
and (in particular) cannot call arbitrary Lisp code. */
+#ifdef SYNC_INPUT
+extern void handle_async_input P_ ((void));
+extern int interrupt_input_pending;
#define QUIT \
do { \
if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \
Vquit_flag = Qnil; \
Fsignal (Qquit, Qnil); \
} \
+ else if (interrupt_input_pending) \
+ handle_async_input (); \
} while (0)
+#else /* not SYNC_INPUT */
+
+#define QUIT \
+ do { \
+ if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \
+ { \
+ Vquit_flag = Qnil; \
+ Fsignal (Qquit, Qnil); \
+ } \
+ } while (0)
+
+#endif /* not SYNC_INPUT */
+
+
/* Nonzero if ought to quit now. */
#define QUITP (!NILP (Vquit_flag) && NILP (Vinhibit_quit))