Lisp_Type_Limit
};
-/* This is the set of datatypes that share a common structure.
+/* This is the set of data types that share a common structure.
The first member of the structure is a type code from this set.
The enum values are arbitrary, but we'll use large numbers to make it
more likely that we'll spot the error if a random word in memory is
/* One need to override this if there must be high bits set in data space
(doing the result of the below & ((1 << (GCTYPE + 1)) - 1) would work
- on all machines, but would penalise machines which don't need it)
+ on all machines, but would penalize machines which don't need it)
*/
#ifndef XTYPE
#define XTYPE(a) ((enum Lisp_Type) ((a) >> VALBITS))
#ifndef XPNTR
#ifdef HAVE_SHM
/* In this representation, data is found in two widely separated segments. */
-extern int pure_size;
+extern size_t pure_size;
#define XPNTR(a) \
(XUINT (a) | (XUINT (a) > pure_size ? DATA_SEG_BITS : PURE_SEG_BITS))
#else /* not HAVE_SHM */
unsigned char data[1];
};
-/* In a symbol, the markbit of the plist is used as the gc mark bit */
-
-struct Lisp_Symbol
- {
- struct Lisp_String *name;
- Lisp_Object value;
- Lisp_Object function;
- Lisp_Object plist;
- Lisp_Object obarray;
- struct Lisp_Symbol *next; /* -> next symbol in this obarray bucket */
- };
-
/* This structure describes a built-in function.
It is generated by the DEFUN macro only.
defsubr makes it into a Lisp object.
char *doc;
};
+\f
+/***********************************************************************
+ Symbols
+ ***********************************************************************/
+
+/* Interned state of a symbol. */
+
+enum symbol_interned
+{
+ SYMBOL_UNINTERNED = 0,
+ SYMBOL_INTERNED = 1,
+ SYMBOL_INTERNED_IN_INITIAL_OBARRAY = 2
+};
+
+/* In a symbol, the markbit of the plist is used as the gc mark bit */
+
+struct Lisp_Symbol
+{
+ /* Non-zero means symbol serves as a variable alias. The symbol
+ holding the real value is found in the value slot. */
+ unsigned indirect_variable : 1;
+
+ /* Non-zero means symbol is constant, i.e. changing its value
+ should signal an error. */
+ unsigned constant : 1;
+
+ /* Interned state of the symbol. This is an enumerator from
+ enum symbol_interned. */
+ unsigned interned : 2;
+
+ /* The symbol's name. This should become a Lisp_Object
+ some day; there's no need for the Lisp_String pointer nowadays. */
+ struct Lisp_String *name;
+
+ /* Value of the symbol or Qunbound if unbound. If this symbol is a
+ defvaralias, `value' contains the symbol for which it is an
+ alias. Use the SYMBOL_VALUE and SET_SYMBOL_VALUE macros to get
+ and set a symbol's value, to take defvaralias into account. */
+ Lisp_Object value;
+
+ /* Function value of the symbol or Qunbound if not fcoundp. */
+ Lisp_Object function;
+
+ /* The symbol's property list. */
+ Lisp_Object plist;
+
+ /* Next symbol in obarray bucket, if the symbol is interned. */
+ struct Lisp_Symbol *next;
+};
+
+/* Value is non-zero if SYM is an interned symbol. */
+
+#define SYMBOL_INTERNED_P(sym) \
+ (XSYMBOL (sym)->interned != SYMBOL_UNINTERNED)
+
+/* Value is non-zero if SYM is interned in initial_obarray. */
+
+#define SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P(sym) \
+ (XSYMBOL (sym)->interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY)
+
+/* Value is non-zero if symbol is considered a constant, i.e. its
+ value cannot be changed (there is an exception for keyword symbols,
+ whose value can be set to the keyword symbol itself). */
+
+#define SYMBOL_CONSTANT_P(sym) XSYMBOL (sym)->constant
+
+/* Value is the value of SYM, with defvaralias taken into
+ account. */
+
+#define SYMBOL_VALUE(sym) \
+ (XSYMBOL (sym)->indirect_variable \
+ ? XSYMBOL (indirect_variable (sym))->value \
+ : XSYMBOL (sym)->value)
+
+/* Set SYM's value to VAL, taking defvaralias into account. */
+
+#define SET_SYMBOL_VALUE(sym, val) \
+ do { \
+ if (XSYMBOL (sym)->indirect_variable) \
+ XSYMBOL (indirect_variable ((sym)))->value = (val); \
+ else \
+ XSYMBOL (sym)->value = (val); \
+ } while (0)
+
\f
/***********************************************************************
Hash Tables
EXFUN (Fsub1, 1);
EXFUN (Fmake_variable_buffer_local, 1);
+extern Lisp_Object indirect_variable P_ ((Lisp_Object));
extern Lisp_Object long_to_cons P_ ((unsigned long));
extern unsigned long cons_to_long P_ ((Lisp_Object));
extern void args_out_of_range P_ ((Lisp_Object, Lisp_Object));
extern void memory_warnings P_ ((POINTER_TYPE *, void (*warnfun) ()));
/* Defined in alloc.c */
+extern void check_pure_size P_ ((void));
extern void allocate_string_data P_ ((struct Lisp_String *, int, int));
extern void uninterrupt_malloc P_ ((void));
extern void malloc_warning P_ ((char *));
#else
#define SWITCH_ENUM_CAST(x) (x)
#endif
+
+/* Loop over Lisp list LIST. Signal an error if LIST is not a proper
+ list, or if it contains circles.
+
+ HARE and TORTOISE should be the names of Lisp_Object variables, and
+ N should be the name of an EMACS_INT variable declared in the
+ function where the macro is used. Each nested loop should use
+ its own variables.
+
+ In the loop body, HARE is set to each cons of LIST, and N is the
+ length of the list processed so far. */
+
+#define LIST_END_P(list, obj) \
+ (NILP (obj) \
+ ? 1 \
+ : (CONSP (obj) \
+ ? 0 \
+ : (wrong_type_argument (Qlistp, (list), 0)), 1))
+
+#define FOREACH(hare, list, tortoise, n) \
+ for (tortoise = hare = (list), n = 0; \
+ !LIST_END_P (list, hare); \
+ (hare = XCDR (hare), ++n, \
+ ((n & 1) != 0 \
+ ? (tortoise = XCDR (tortoise), \
+ (EQ (hare, tortoise) \
+ && (circular_list_error ((list)), 1))) \
+ : 0)))