Emacs Lispのシンボルの定義を確認したくなった。
struct Lisp_Symbol
{
union
{
struct
{
bool_bf gcmarkbit : 1;
/* Indicates where the value can be found. */
ENUM_BF (symbol_redirect) redirect : 2;
ENUM_BF (symbol_trapped_write) trapped_write : 2;
/* Interned state of the symbol. */
ENUM_BF (symbol_interned) interned : 2;
/* True means that this variable has been explicitly declared
special (with `defvar' etc), and shouldn't be lexically bound. */
bool_bf declared_special : 1;
/* True if pointed to from purespace and hence can't be GC'd. */
bool_bf pinned : 1;
/* The symbol's name, as a Lisp string. */
Lisp_Object name;
/* Value of the symbol or Qunbound if unbound. Which alternative of the
union is used depends on the `redirect' field above. */
union {
Lisp_Object value;
struct Lisp_Symbol *alias;
struct Lisp_Buffer_Local_Value *blv;
lispfwd fwd;
} val;
/* Function value of the symbol or Qnil if not fboundp. */
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;
} s;
GCALIGNED_UNION_MEMBER
} u;
};
name
はシンボル名、 val
は値セル function
は関数セルといった感じだろうか。
ついでに fset
の定義も確認する。
DEFUN ("fset", Ffset, Sfset, 2, 2, 0,
doc: /* Set SYMBOL's function definition to DEFINITION, and return DEFINITION.
If the resulting chain of function definitions would contain a loop,
signal a `cyclic-function-indirection' error. */)
(register Lisp_Object symbol, Lisp_Object definition)
{
CHECK_SYMBOL (symbol);
/* Perhaps not quite the right error signal, but seems good enough. */
if (NILP (symbol) && !NILP (definition))
/* There are so many other ways to shoot oneself in the foot, I don't
think this one little sanity check is worth its cost, but anyway. */
xsignal1 (Qsetting_constant, symbol);
eassert (valid_lisp_object_p (definition));
/* Ensure non-circularity. */
for (Lisp_Object s = definition; SYMBOLP (s) && !NILP (s);
s = XSYMBOL (s)->u.s.function)
if (EQ (s, symbol))
xsignal1 (Qcyclic_function_indirection, symbol);
#ifdef HAVE_NATIVE_COMP
register Lisp_Object function = XSYMBOL (symbol)->u.s.function;
if (!NILP (Vnative_comp_enable_subr_trampolines)
&& SUBRP (function)
&& !SUBR_NATIVE_COMPILEDP (function))
CALLN (Ffuncall, Qcomp_subr_trampoline_install, symbol);
#endif
set_symbol_function (symbol, definition);
return definition;
}
いろいろな処理を行っているが、本質的な部分は最後の方に実行している set_symbol_function (symbol, definition);
となる。そこで set_symbol_function
についても確認する。
INLINE void
set_symbol_function (Lisp_Object sym, Lisp_Object function)
{
XSYMBOL (sym)->u.s.function = function;
}
(sym)->u.s.function
は第1引数に渡したLisp_Object symの共用体uの先頭に配置されている構造体sの function
スロットだ。そこに第2引数に渡したLisp_Object functionを代入している。なるほど。少し理解できた。