guile-elisp bootstrap (C)
[bpt/emacs.git] / src / eval.c
index 3d8573f..cf086a8 100644 (file)
@@ -225,7 +225,6 @@ make_catch_handler (Lisp_Object tag)
   c->body = Qnil;
   c->next = handlerlist;
   c->lisp_eval_depth = lisp_eval_depth;
-  c->poll_suppress_count = poll_suppress_count;
   c->interrupt_input_blocked = interrupt_input_blocked;
   c->ptag = make_prompt_tag ();
   return c;
@@ -242,7 +241,6 @@ make_condition_handler (Lisp_Object tag)
   c->body = Qnil;
   c->next = handlerlist;
   c->lisp_eval_depth = lisp_eval_depth;
-  c->poll_suppress_count = poll_suppress_count;
   c->interrupt_input_blocked = interrupt_input_blocked;
   c->ptag = make_prompt_tag ();
   return c;
@@ -353,58 +351,6 @@ do_debug_on_call (Lisp_Object code)
   call_debugger (list1 (code));
 }
 \f
-/* NOTE!!! Every function that can call EVAL must protect its args
-   and temporaries from garbage collection while it needs them.
-   The definition of `For' shows what you have to do.  */
-
-DEFUN ("or", For, Sor, 0, UNEVALLED, 0,
-       doc: /* Eval args until one of them yields non-nil, then return that value.
-The remaining args are not evalled at all.
-If all args return nil, return nil.
-usage: (or CONDITIONS...)  */)
-  (Lisp_Object args)
-{
-  register Lisp_Object val = Qnil;
-  struct gcpro gcpro1;
-
-  GCPRO1 (args);
-
-  while (CONSP (args))
-    {
-      val = eval_sub (XCAR (args));
-      if (!NILP (val))
-       break;
-      args = XCDR (args);
-    }
-
-  UNGCPRO;
-  return val;
-}
-
-DEFUN ("and", Fand, Sand, 0, UNEVALLED, 0,
-       doc: /* Eval args until one of them yields nil, then return nil.
-The remaining args are not evalled at all.
-If no arg yields nil, return the last arg's value.
-usage: (and CONDITIONS...)  */)
-  (Lisp_Object args)
-{
-  register Lisp_Object val = Qt;
-  struct gcpro gcpro1;
-
-  GCPRO1 (args);
-
-  while (CONSP (args))
-    {
-      val = eval_sub (XCAR (args));
-      if (NILP (val))
-       break;
-      args = XCDR (args);
-    }
-
-  UNGCPRO;
-  return val;
-}
-
 DEFUN ("if", Fif, Sif, 2, UNEVALLED, 0,
        doc: /* If COND yields non-nil, do THEN, else do ELSE...
 Returns the value of THEN or the value of the last of the ELSE's.
@@ -425,39 +371,6 @@ usage: (if COND THEN ELSE...)  */)
   return Fprogn (XCDR (XCDR (args)));
 }
 
-DEFUN ("cond", Fcond, Scond, 0, UNEVALLED, 0,
-       doc: /* Try each clause until one succeeds.
-Each clause looks like (CONDITION BODY...).  CONDITION is evaluated
-and, if the value is non-nil, this clause succeeds:
-then the expressions in BODY are evaluated and the last one's
-value is the value of the cond-form.
-If a clause has one element, as in (CONDITION), then the cond-form
-returns CONDITION's value, if that is non-nil.
-If no clause succeeds, cond returns nil.
-usage: (cond CLAUSES...)  */)
-  (Lisp_Object args)
-{
-  Lisp_Object val = args;
-  struct gcpro gcpro1;
-
-  GCPRO1 (args);
-  while (CONSP (args))
-    {
-      Lisp_Object clause = XCAR (args);
-      val = eval_sub (Fcar (clause));
-      if (!NILP (val))
-       {
-         if (!NILP (XCDR (clause)))
-           val = Fprogn (XCDR (clause));
-         break;
-       }
-      args = XCDR (args);
-    }
-  UNGCPRO;
-
-  return val;
-}
-
 DEFUN ("progn", Fprogn, Sprogn, 0, UNEVALLED, 0,
        doc: /* Eval BODY forms sequentially and return value of last one.
 usage: (progn BODY...)  */)
@@ -487,44 +400,6 @@ unwind_body (Lisp_Object body)
   Fprogn (body);
 }
 
-DEFUN ("prog1", Fprog1, Sprog1, 1, UNEVALLED, 0,
-       doc: /* Eval FIRST and BODY sequentially; return value from FIRST.
-The value of FIRST is saved during the evaluation of the remaining args,
-whose values are discarded.
-usage: (prog1 FIRST BODY...)  */)
-  (Lisp_Object args)
-{
-  Lisp_Object val;
-  Lisp_Object args_left;
-  struct gcpro gcpro1, gcpro2;
-
-  args_left = args;
-  val = args;
-  GCPRO2 (args, val);
-
-  val = eval_sub (XCAR (args_left));
-  while (CONSP (args_left = XCDR (args_left)))
-    eval_sub (XCAR (args_left));
-
-  UNGCPRO;
-  return val;
-}
-
-DEFUN ("prog2", Fprog2, Sprog2, 2, UNEVALLED, 0,
-       doc: /* Eval FORM1, FORM2 and BODY sequentially; return value from FORM2.
-The value of FORM2 is saved during the evaluation of the
-remaining args, whose values are discarded.
-usage: (prog2 FORM1 FORM2 BODY...)  */)
-  (Lisp_Object args)
-{
-  struct gcpro gcpro1;
-
-  GCPRO1 (args);
-  eval_sub (XCAR (args));
-  UNGCPRO;
-  return Fprog1 (XCDR (args));
-}
-
 DEFUN ("setq", Fsetq, Ssetq, 0, UNEVALLED, 0,
        doc: /* Set each SYM to the value of its VAL.
 The symbols SYM are variables; they are literal (not evaluated).
@@ -624,18 +499,18 @@ then the value of BASE-VARIABLE is set to that of NEW-ALIAS.
 The return value is BASE-VARIABLE.  */)
   (Lisp_Object new_alias, Lisp_Object base_variable, Lisp_Object docstring)
 {
-  struct Lisp_Symbol *sym;
+  sym_t sym;
 
   CHECK_SYMBOL (new_alias);
   CHECK_SYMBOL (base_variable);
 
   sym = XSYMBOL (new_alias);
 
-  if (sym->constant)
+  if (SYMBOL_CONSTANT (sym))
     /* Not sure why, but why not?  */
     error ("Cannot make a constant an alias");
 
-  switch (sym->redirect)
+  switch (SYMBOL_REDIRECT (sym))
     {
     case SYMBOL_FORWARDED:
       error ("Cannot make an internal variable an alias");
@@ -659,11 +534,11 @@ The return value is BASE-VARIABLE.  */)
        error ("Don't know how to make a let-bound variable an alias");
   }
 
-  sym->declared_special = 1;
-  XSYMBOL (base_variable)->declared_special = 1;
-  sym->redirect = SYMBOL_VARALIAS;
+  SET_SYMBOL_DECLARED_SPECIAL (sym, 1);
+  SET_SYMBOL_DECLARED_SPECIAL (XSYMBOL (base_variable), 1);
+  SET_SYMBOL_REDIRECT (sym, SYMBOL_VARALIAS);
   SET_SYMBOL_ALIAS (sym, XSYMBOL (base_variable));
-  sym->constant = SYMBOL_CONSTANT_P (base_variable);
+  SET_SYMBOL_CONSTANT (sym, SYMBOL_CONSTANT_P (base_variable));
   LOADHIST_ATTACH (new_alias);
   /* Even if docstring is nil: remove old docstring.  */
   Fput (new_alias, Qvariable_documentation, docstring);
@@ -757,7 +632,7 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING)  */)
       tem = Fdefault_boundp (sym);
 
       /* Do it before evaluating the initial value, for self-references.  */
-      XSYMBOL (sym)->declared_special = 1;
+      SET_SYMBOL_DECLARED_SPECIAL (XSYMBOL (sym), 1);
 
       if (NILP (tem))
        Fset_default (sym, eval_sub (XCAR (tail)));
@@ -781,7 +656,7 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING)  */)
       LOADHIST_ATTACH (sym);
     }
   else if (!NILP (Vinternal_interpreter_environment)
-          && !XSYMBOL (sym)->declared_special)
+          && ! SYMBOL_DECLARED_SPECIAL (XSYMBOL (sym)))
     /* A simple (defvar foo) with lexical scoping does "nothing" except
        declare that var to be dynamically scoped *locally* (i.e. within
        the current file or let-block).  */
@@ -825,7 +700,7 @@ usage: (defconst SYMBOL INITVALUE [DOCSTRING])  */)
   if (!NILP (Vpurify_flag))
     tem = Fpurecopy (tem);
   Fset_default (sym, tem);
-  XSYMBOL (sym)->declared_special = 1;
+  SET_SYMBOL_DECLARED_SPECIAL (XSYMBOL (sym), 1);
   tem = Fcar (XCDR (XCDR (args)));
   if (!NILP (tem))
     {
@@ -845,7 +720,7 @@ DEFUN ("internal-make-var-non-special", Fmake_var_non_special,
      (Lisp_Object symbol)
 {
   CHECK_SYMBOL (symbol);
-  XSYMBOL (symbol)->declared_special = 0;
+  SET_SYMBOL_DECLARED_SPECIAL (XSYMBOL (symbol), 0);
   return Qnil;
 }
 
@@ -887,7 +762,7 @@ usage: (let* VARLIST BODY...)  */)
        }
 
       if (!NILP (lexenv) && SYMBOLP (var)
-         && !XSYMBOL (var)->declared_special
+         && ! SYMBOL_DECLARED_SPECIAL (XSYMBOL (var))
          && NILP (Fmemq (var, Vinternal_interpreter_environment)))
        /* Lexically bind VAR by adding it to the interpreter's binding
           alist.  */
@@ -966,7 +841,7 @@ usage: (let VARLIST BODY...)  */)
       tem = temps[argnum++];
 
       if (!NILP (lexenv) && SYMBOLP (var)
-         && !XSYMBOL (var)->declared_special
+         && ! SYMBOL_DECLARED_SPECIAL (XSYMBOL (var))
          && NILP (Fmemq (var, Vinternal_interpreter_environment)))
        /* Lexically bind VAR by adding it to the lexenv alist.  */
        lexenv = Fcons (Fcons (var, tem), lexenv);
@@ -1040,7 +915,7 @@ definitions to shadow the loaded ones for use in file byte-compilation.  */)
          tem = Fassq (sym, environment);
          if (NILP (tem))
            {
-             def = XSYMBOL (sym)->function;
+             def = SYMBOL_FUNCTION (sym);
              if (!NILP (def))
                continue;
            }
@@ -1116,7 +991,6 @@ static void
 restore_handler (void *data)
 {
   struct handler *c = data;
-  set_poll_suppress_count (c->poll_suppress_count);
   unblock_input_to (c->interrupt_input_blocked);
   immediate_quit = 0;
 }
@@ -1872,11 +1746,9 @@ then strings and vectors are not accepted.  */)
       fun = Fsymbol_function (fun);
     }
 
-  /* Emacs primitives are interactive if their DEFUN specifies an
-     interactive spec.  */
-  if (SUBRP (fun))
-    return XSUBR (fun)->intspec ? Qt : if_prop;
-
+  if (scm_is_true (scm_procedure_p (fun)))
+    return (scm_is_true (scm_procedure_property (fun, Qinteractive_form))
+            ? Qt : if_prop);
   /* Bytecode objects are interactive if they are long enough to
      have an element whose index is COMPILED_INTERACTIVE, which is
      where the interactive spec is stored.  */
@@ -1922,8 +1794,8 @@ this does nothing and returns nil.  */)
   CHECK_STRING (file);
 
   /* If function is defined and not as an autoload, don't override.  */
-  if (!NILP (XSYMBOL (function)->function)
-      && !AUTOLOADP (XSYMBOL (function)->function))
+  if (!NILP (SYMBOL_FUNCTION (function))
+      && !AUTOLOADP (SYMBOL_FUNCTION (function)))
     return Qnil;
 
   return Fdefalias (function,
@@ -2163,120 +2035,30 @@ eval_sub_1 (Lisp_Object form)
   fun = original_fun;
   if (!SYMBOLP (fun))
     fun = Ffunction (Fcons (fun, Qnil));
-  else if (!NILP (fun) && (fun = XSYMBOL (fun)->function, SYMBOLP (fun)))
+  else if (!NILP (fun) && (fun = SYMBOL_FUNCTION (fun), SYMBOLP (fun)))
     fun = indirect_function (fun);
 
-  if (SUBRP (fun))
+  if (scm_is_true (scm_procedure_p (fun)))
     {
-      Lisp_Object numargs;
-      Lisp_Object argvals[8];
-      Lisp_Object args_left;
-      register int i, maxargs;
-
-      args_left = original_args;
-      numargs = Flength (args_left);
-
-      if (XINT (numargs) < XSUBR (fun)->min_args
-         || (XSUBR (fun)->max_args >= 0
-             && XSUBR (fun)->max_args < XINT (numargs)))
-       xsignal2 (Qwrong_number_of_arguments, original_fun, numargs);
-
-      else if (XSUBR (fun)->max_args == UNEVALLED)
-       val = (XSUBR (fun)->function.aUNEVALLED) (args_left);
-      else if (XSUBR (fun)->max_args == MANY)
-       {
-         /* Pass a vector of evaluated arguments.  */
-         Lisp_Object *vals;
-         ptrdiff_t argnum = 0;
-         USE_SAFE_ALLOCA;
-
-         SAFE_ALLOCA_LISP (vals, XINT (numargs));
-
-         GCPRO3 (args_left, fun, fun);
-         gcpro3.var = vals;
-         gcpro3.nvars = 0;
-
-         while (!NILP (args_left))
-           {
-             vals[argnum++] = eval_sub (Fcar (args_left));
-             args_left = Fcdr (args_left);
-             gcpro3.nvars = argnum;
-           }
-
-         set_backtrace_args (specpdl_ptr - 1, vals);
-         set_backtrace_nargs (specpdl_ptr - 1, XINT (numargs));
-
-         val = (XSUBR (fun)->function.aMANY) (XINT (numargs), vals);
-         UNGCPRO;
-         SAFE_FREE ();
-       }
-      else
-       {
-         GCPRO3 (args_left, fun, fun);
-         gcpro3.var = argvals;
-         gcpro3.nvars = 0;
-
-         maxargs = XSUBR (fun)->max_args;
-         for (i = 0; i < maxargs; args_left = Fcdr (args_left))
-           {
-             argvals[i] = eval_sub (Fcar (args_left));
-             gcpro3.nvars = ++i;
-           }
-
-         UNGCPRO;
+      Lisp_Object args_left = original_args;
+      Lisp_Object nargs = Flength (args_left);
+      Lisp_Object *args;
+      size_t argnum = 0;
 
-         set_backtrace_args (specpdl_ptr - 1, argvals);
-         set_backtrace_nargs (specpdl_ptr - 1, XINT (numargs));
+      SAFE_ALLOCA_LISP (args, XINT (nargs));
 
-         switch (i)
-           {
-           case 0:
-             val = (XSUBR (fun)->function.a0 ());
-             break;
-           case 1:
-             val = (XSUBR (fun)->function.a1 (argvals[0]));
-             break;
-           case 2:
-             val = (XSUBR (fun)->function.a2 (argvals[0], argvals[1]));
-             break;
-           case 3:
-             val = (XSUBR (fun)->function.a3
-                    (argvals[0], argvals[1], argvals[2]));
-             break;
-           case 4:
-             val = (XSUBR (fun)->function.a4
-                    (argvals[0], argvals[1], argvals[2], argvals[3]));
-             break;
-           case 5:
-             val = (XSUBR (fun)->function.a5
-                    (argvals[0], argvals[1], argvals[2], argvals[3],
-                     argvals[4]));
-             break;
-           case 6:
-             val = (XSUBR (fun)->function.a6
-                    (argvals[0], argvals[1], argvals[2], argvals[3],
-                     argvals[4], argvals[5]));
-             break;
-           case 7:
-             val = (XSUBR (fun)->function.a7
-                    (argvals[0], argvals[1], argvals[2], argvals[3],
-                     argvals[4], argvals[5], argvals[6]));
-             break;
-
-           case 8:
-             val = (XSUBR (fun)->function.a8
-                    (argvals[0], argvals[1], argvals[2], argvals[3],
-                     argvals[4], argvals[5], argvals[6], argvals[7]));
-             break;
-
-           default:
-             /* Someone has created a subr that takes more arguments than
-                is supported by this code.  We need to either rewrite the
-                subr to use a different argument protocol, or add more
-                cases to this switch.  */
-             emacs_abort ();
-           }
-       }
+      while (! NILP (args_left))
+        {
+          args[argnum++] = eval_sub (Fcar (args_left));
+          args_left = Fcdr (args_left);
+        }
+      set_backtrace_args (specpdl_ptr - 1, args);
+      set_backtrace_nargs (specpdl_ptr - 1, argnum);
+      val = scm_call_n (fun, args, argnum);
+    }
+  else if (CONSP (fun) && EQ (XCAR (fun), Qspecial_operator))
+    {
+      val = scm_apply_0 (XCDR (fun), original_args);
     }
   else if (COMPILEDP (fun))
     val = apply_lambda (fun, original_args);
@@ -2391,32 +2173,14 @@ usage: (apply FUNCTION &rest ARGUMENTS)  */)
 
   /* Optimize for no indirection.  */
   if (SYMBOLP (fun) && !NILP (fun)
-      && (fun = XSYMBOL (fun)->function, SYMBOLP (fun)))
+      && (fun = SYMBOL_FUNCTION (fun), SYMBOLP (fun)))
     fun = indirect_function (fun);
   if (NILP (fun))
     {
       /* Let funcall get the error.  */
       fun = args[0];
-      goto funcall;
     }
 
-  if (SUBRP (fun))
-    {
-      if (numargs < XSUBR (fun)->min_args
-         || (XSUBR (fun)->max_args >= 0 && XSUBR (fun)->max_args < numargs))
-       goto funcall;           /* Let funcall get the error.  */
-      else if (XSUBR (fun)->max_args >= 0 && XSUBR (fun)->max_args > numargs)
-       {
-         /* Avoid making funcall cons up a yet another new vector of arguments
-            by explicitly supplying nil's for optional values.  */
-         SAFE_ALLOCA_LISP (funcall_args, 1 + XSUBR (fun)->max_args);
-         for (i = numargs; i < XSUBR (fun)->max_args;)
-           funcall_args[++i] = Qnil;
-         GCPRO1 (*funcall_args);
-         gcpro1.nvars = 1 + XSUBR (fun)->max_args;
-       }
-    }
- funcall:
   /* We add 1 to numargs because funcall_args includes the
      function itself as well as its arguments.  */
   if (!funcall_args)
@@ -2866,88 +2630,12 @@ usage: (funcall FUNCTION &rest ARGUMENTS)  */)
   /* Optimize for no indirection.  */
   fun = original_fun;
   if (SYMBOLP (fun) && !NILP (fun)
-      && (fun = XSYMBOL (fun)->function, SYMBOLP (fun)))
+      && (fun = SYMBOL_FUNCTION (fun), SYMBOLP (fun)))
     fun = indirect_function (fun);
 
-  if (SUBRP (fun))
+  if (scm_is_true (scm_procedure_p (fun)))
     {
-      if (numargs < XSUBR (fun)->min_args
-         || (XSUBR (fun)->max_args >= 0 && XSUBR (fun)->max_args < numargs))
-       {
-         XSETFASTINT (lisp_numargs, numargs);
-         xsignal2 (Qwrong_number_of_arguments, original_fun, lisp_numargs);
-       }
-
-      else if (XSUBR (fun)->max_args == UNEVALLED)
-       xsignal1 (Qinvalid_function, original_fun);
-
-      else if (XSUBR (fun)->max_args == MANY)
-       val = (XSUBR (fun)->function.aMANY) (numargs, args + 1);
-      else
-       {
-         if (XSUBR (fun)->max_args > numargs)
-           {
-             internal_args = alloca (XSUBR (fun)->max_args
-                                     * sizeof *internal_args);
-             memcpy (internal_args, args + 1, numargs * word_size);
-             for (i = numargs; i < XSUBR (fun)->max_args; i++)
-               internal_args[i] = Qnil;
-           }
-         else
-           internal_args = args + 1;
-         switch (XSUBR (fun)->max_args)
-           {
-           case 0:
-             val = (XSUBR (fun)->function.a0 ());
-             break;
-           case 1:
-             val = (XSUBR (fun)->function.a1 (internal_args[0]));
-             break;
-           case 2:
-             val = (XSUBR (fun)->function.a2
-                    (internal_args[0], internal_args[1]));
-             break;
-           case 3:
-             val = (XSUBR (fun)->function.a3
-                    (internal_args[0], internal_args[1], internal_args[2]));
-             break;
-           case 4:
-             val = (XSUBR (fun)->function.a4
-                    (internal_args[0], internal_args[1], internal_args[2],
-                    internal_args[3]));
-             break;
-           case 5:
-             val = (XSUBR (fun)->function.a5
-                    (internal_args[0], internal_args[1], internal_args[2],
-                     internal_args[3], internal_args[4]));
-             break;
-           case 6:
-             val = (XSUBR (fun)->function.a6
-                    (internal_args[0], internal_args[1], internal_args[2],
-                     internal_args[3], internal_args[4], internal_args[5]));
-             break;
-           case 7:
-             val = (XSUBR (fun)->function.a7
-                    (internal_args[0], internal_args[1], internal_args[2],
-                     internal_args[3], internal_args[4], internal_args[5],
-                     internal_args[6]));
-             break;
-
-           case 8:
-             val = (XSUBR (fun)->function.a8
-                    (internal_args[0], internal_args[1], internal_args[2],
-                     internal_args[3], internal_args[4], internal_args[5],
-                     internal_args[6], internal_args[7]));
-             break;
-
-           default:
-
-             /* If a subr takes more than 8 arguments without using MANY
-                or UNEVALLED, we need to extend this function to support it.
-                Until this is done, there is no way to call the function.  */
-             emacs_abort ();
-           }
-       }
+      val = scm_call_n (fun, args + 1, numargs);
     }
   else if (COMPILEDP (fun))
     val = funcall_lambda (fun, numargs, args + 1);
@@ -3177,7 +2865,7 @@ DEFUN ("fetch-bytecode", Ffetch_bytecode, Sfetch_bytecode,
    which was made in the buffer that is now current.  */
 
 bool
-let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol)
+let_shadows_buffer_binding_p (sym_t symbol)
 {
   union specbinding *p;
   Lisp_Object buf = Fcurrent_buffer ();
@@ -3185,8 +2873,8 @@ let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol)
   for (p = specpdl_ptr; p > specpdl; )
     if ((--p)->kind > SPECPDL_LET)
       {
-       struct Lisp_Symbol *let_bound_symbol = XSYMBOL (specpdl_symbol (p));
-       eassert (let_bound_symbol->redirect != SYMBOL_VARALIAS);
+       sym_t let_bound_symbol = XSYMBOL (specpdl_symbol (p));
+       eassert (SYMBOL_REDIRECT (let_bound_symbol) != SYMBOL_VARALIAS);
        if (symbol == let_bound_symbol
            && EQ (specpdl_where (p), buf))
          return 1;
@@ -3222,13 +2910,13 @@ let_shadows_global_binding_p (Lisp_Object symbol)
 void
 specbind (Lisp_Object symbol, Lisp_Object value)
 {
-  struct Lisp_Symbol *sym;
+  sym_t sym;
 
   CHECK_SYMBOL (symbol);
   sym = XSYMBOL (symbol);
 
  start:
-  switch (sym->redirect)
+  switch (SYMBOL_REDIRECT (sym))
     {
     case SYMBOL_VARALIAS:
       sym = indirect_variable (sym); XSETSYMBOL (symbol, sym); goto start;
@@ -3239,7 +2927,7 @@ specbind (Lisp_Object symbol, Lisp_Object value)
       specpdl_ptr->let.symbol = symbol;
       specpdl_ptr->let.old_value = SYMBOL_VAL (sym);
       grow_specpdl ();
-      if (!sym->constant)
+      if (! SYMBOL_CONSTANT (sym))
        SET_SYMBOL_VAL (sym, value);
       else
        set_internal (symbol, value, Qnil, 1);
@@ -3255,10 +2943,10 @@ specbind (Lisp_Object symbol, Lisp_Object value)
        specpdl_ptr->let.old_value = ovalue;
        specpdl_ptr->let.where = Fcurrent_buffer ();
 
-       eassert (sym->redirect != SYMBOL_LOCALIZED
+       eassert (SYMBOL_REDIRECT (sym) != SYMBOL_LOCALIZED
                 || (EQ (SYMBOL_BLV (sym)->where, Fcurrent_buffer ())));
 
-       if (sym->redirect == SYMBOL_LOCALIZED)
+       if (SYMBOL_REDIRECT (sym) == SYMBOL_LOCALIZED)
          {
            if (!blv_found (SYMBOL_BLV (sym)))
              specpdl_ptr->let.kind = SPECPDL_LET_DEFAULT;
@@ -3374,8 +3062,8 @@ unbind_once (void *ignore)
       { /* If variable has a trivial value (no forwarding), we can
            just set it.  No need to check for constant symbols here,
            since that was already done by specbind.  */
-        struct Lisp_Symbol *sym = XSYMBOL (specpdl_symbol (specpdl_ptr));
-        if (sym->redirect == SYMBOL_PLAINVAL)
+        sym_t sym = XSYMBOL (specpdl_symbol (specpdl_ptr));
+        if (SYMBOL_REDIRECT (sym) == SYMBOL_PLAINVAL)
           {
             SET_SYMBOL_VAL (sym, specpdl_old_value (specpdl_ptr));
             break;
@@ -3425,7 +3113,7 @@ context where binding is lexical by default.  */)
   (Lisp_Object symbol)
 {
    CHECK_SYMBOL (symbol);
-   return XSYMBOL (symbol)->declared_special ? Qt : Qnil;
+   return SYMBOL_DECLARED_SPECIAL (XSYMBOL (symbol)) ? Qt : Qnil;
 }
 
 \f
@@ -3574,8 +3262,8 @@ backtrace_eval_unrewind (int distance)
          { /* If variable has a trivial value (no forwarding), we can
               just set it.  No need to check for constant symbols here,
               since that was already done by specbind.  */
-           struct Lisp_Symbol *sym = XSYMBOL (specpdl_symbol (tmp));
-           if (sym->redirect == SYMBOL_PLAINVAL)
+           sym_t sym = XSYMBOL (specpdl_symbol (tmp));
+           if (SYMBOL_REDIRECT (sym) == SYMBOL_PLAINVAL)
              {
                Lisp_Object old_value = specpdl_old_value (tmp);
                set_specpdl_old_value (tmp, SYMBOL_VAL (sym));