(C6-3930): Add M-17478.
[chise/xemacs-chise.git-] / src / data.c
index 0bfe462..a0f2445 100644 (file)
@@ -1,6 +1,7 @@
 /* Primitive operations on Lisp data types for XEmacs Lisp interpreter.
    Copyright (C) 1985, 1986, 1988, 1992, 1993, 1994, 1995
    Free Software Foundation, Inc.
+   Copyright (C) 2000 Ben Wing.
 
 This file is part of XEmacs.
 
@@ -39,25 +40,30 @@ Boston, MA 02111-1307, USA.  */
 
 Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound;
 Lisp_Object Qerror_conditions, Qerror_message;
-Lisp_Object Qerror, Qquit, Qwrong_type_argument, Qargs_out_of_range;
-Lisp_Object Qvoid_variable, Qcyclic_variable_indirection;
-Lisp_Object Qvoid_function, Qcyclic_function_indirection;
-Lisp_Object Qsetting_constant, Qinvalid_read_syntax;
+Lisp_Object Qerror, Qquit, Qsyntax_error, Qinvalid_read_syntax;
+Lisp_Object Qlist_formation_error;
 Lisp_Object Qmalformed_list, Qmalformed_property_list;
 Lisp_Object Qcircular_list, Qcircular_property_list;
-Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch;
+Lisp_Object Qinvalid_argument, Qwrong_type_argument, Qargs_out_of_range;
+Lisp_Object Qwrong_number_of_arguments, Qinvalid_function, Qno_catch;
+Lisp_Object Qinternal_error, Qinvalid_state;
+Lisp_Object Qvoid_variable, Qcyclic_variable_indirection;
+Lisp_Object Qvoid_function, Qcyclic_function_indirection;
+Lisp_Object Qinvalid_operation, Qinvalid_change;
+Lisp_Object Qsetting_constant;
+Lisp_Object Qediting_error;
+Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;
 Lisp_Object Qio_error, Qend_of_file;
 Lisp_Object Qarith_error, Qrange_error, Qdomain_error;
 Lisp_Object Qsingularity_error, Qoverflow_error, Qunderflow_error;
-Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;
-Lisp_Object Qintegerp, Qnatnump, Qsymbolp, Qkeywordp;
+Lisp_Object Qintegerp, Qnatnump, Qsymbolp;
 Lisp_Object Qlistp, Qtrue_list_p, Qweak_listp;
 Lisp_Object Qconsp, Qsubrp;
 Lisp_Object Qcharacterp, Qstringp, Qarrayp, Qsequencep, Qvectorp;
 Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qbufferp;
 Lisp_Object Qinteger_or_char_p, Qinteger_char_or_marker_p;
-Lisp_Object Qnumberp, Qnumber_or_marker_p, Qnumber_char_or_marker_p;
-Lisp_Object Qbit_vectorp, Qbitp, Qcons, Qkeyword, Qcdr, Qignore;
+Lisp_Object Qnumberp, Qnumber_char_or_marker_p;
+Lisp_Object Qbit_vectorp, Qbitp, Qcdr;
 
 Lisp_Object Qfloatp;
 
@@ -147,7 +153,7 @@ args_out_of_range_3 (Lisp_Object a1, Lisp_Object a2, Lisp_Object a3)
 }
 
 void
-check_int_range (int val, int min, int max)
+check_int_range (EMACS_INT val, EMACS_INT min, EMACS_INT max)
 {
   if (val < min || val > max)
     args_out_of_range_3 (make_int (val), make_int (min), make_int (max));
@@ -160,8 +166,8 @@ EMACS_INT sign_extend_temp;
 
 /* On a few machines, XINT can only be done by calling this.  */
 /* XEmacs:  only used by m/convex.h */
-int sign_extend_lisp_int (EMACS_INT num);
-int
+EMACS_INT sign_extend_lisp_int (EMACS_INT num);
+EMACS_INT
 sign_extend_lisp_int (EMACS_INT num)
 {
   if (num & (1L << (VALBITS - 1)))
@@ -357,7 +363,7 @@ If non-nil, the return value will be a list whose first element is
 */
        (subr))
 {
-  CONST char *prompt;
+  const char *prompt;
   CHECK_SUBR (subr);
   prompt = XSUBR (subr)->prompt;
   return prompt ? list2 (Qinteractive, build_string (prompt)) : Qnil;
@@ -615,7 +621,6 @@ Set the car of CONSCELL to be NEWCAR.  Return NEWCAR.
   if (!CONSP (conscell))
     conscell = wrong_type_argument (Qconsp, conscell);
 
-  CHECK_LISP_WRITEABLE (conscell);
   XCAR (conscell) = newcar;
   return newcar;
 }
@@ -628,7 +633,6 @@ Set the cdr of CONSCELL to be NEWCDR.  Return NEWCDR.
   if (!CONSP (conscell))
     conscell = wrong_type_argument (Qconsp, conscell);
 
-  CHECK_LISP_WRITEABLE (conscell);
   XCDR (conscell) = newcdr;
   return newcdr;
 }
@@ -640,10 +644,11 @@ Set the cdr of CONSCELL to be NEWCDR.  Return NEWCDR.
    return it.  If there is a cycle in the function chain, signal a
    cyclic-function-indirection error.
 
-   This is like Findirect_function, except that it doesn't signal an
-   error if the chain ends up unbound.  */
+   This is like Findirect_function when VOID_FUNCTION_ERRORP is true.
+   When VOID_FUNCTION_ERRORP is false, no error is signaled if the end
+   of the chain ends up being Qunbound. */
 Lisp_Object
-indirect_function (Lisp_Object object, int errorp)
+indirect_function (Lisp_Object object, int void_function_errorp)
 {
 #define FUNCTION_INDIRECTION_SUSPICION_LENGTH 16
   Lisp_Object tortoise, hare;
@@ -661,8 +666,8 @@ indirect_function (Lisp_Object object, int errorp)
        return Fsignal (Qcyclic_function_indirection, list1 (object));
     }
 
-  if (errorp && UNBOUNDP (hare))
-    signal_void_function_error (object);
+  if (void_function_errorp && UNBOUNDP (hare))
+    return signal_void_function_error (object);
 
   return hare;
 }
@@ -689,7 +694,7 @@ ARRAY may be a vector, bit vector, or string.  INDEX starts at 0.
 */
        (array, index_))
 {
-  int idx;
+  EMACS_INT idx;
 
  retry:
 
@@ -743,7 +748,7 @@ ARRAY may be a vector, bit vector, or string.  INDEX starts at 0.
 */
        (array, index_, newval))
 {
-  int idx;
+  EMACS_INT idx;
 
  retry:
 
@@ -757,8 +762,6 @@ ARRAY may be a vector, bit vector, or string.  INDEX starts at 0.
 
   if (idx < 0) goto range_error;
 
-  CHECK_LISP_WRITEABLE (array);
-
   if (VECTORP (array))
     {
       if (idx >= XVECTOR_LENGTH (array)) goto range_error;
@@ -839,7 +842,7 @@ number_char_or_marker_to_double (Lisp_Object obj)
     }
 }
 
-static int
+static EMACS_INT
 integer_char_or_marker_to_int (Lisp_Object obj)
 {
  retry:
@@ -1068,7 +1071,7 @@ Floating point numbers always use base 10.
     p++;
 
 #ifdef LISP_FLOAT_TYPE
-  if (isfloat_string (p))
+  if (isfloat_string (p) && b == 10)
     return make_float (atof (p));
 #endif /* LISP_FLOAT_TYPE */
 
@@ -1416,8 +1419,8 @@ Both must be integers, characters or markers.
 */
        (num1, num2))
 {
-  int ival1 = integer_char_or_marker_to_int (num1);
-  int ival2 = integer_char_or_marker_to_int (num2);
+  EMACS_INT ival1 = integer_char_or_marker_to_int (num1);
+  EMACS_INT ival2 = integer_char_or_marker_to_int (num2);
 
   if (ival2 == 0)
     Fsignal (Qarith_error, Qnil);
@@ -1468,7 +1471,7 @@ If either argument is a float, a float will be returned.
     }
 #endif /* LISP_FLOAT_TYPE */
   {
-    int ival;
+    EMACS_INT ival;
     if (iod2.c.ival == 0) goto divide_by_zero;
 
     ival = iod1.c.ival % iod2.c.ival;
@@ -1570,7 +1573,7 @@ static Lisp_Object Vall_weak_lists; /* Gemarke es nicht!!! */
 static Lisp_Object encode_weak_list_type (enum weak_list_type type);
 
 static Lisp_Object
-mark_weak_list (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_weak_list (Lisp_Object obj)
 {
   return Qnil; /* nichts ist gemarkt */
 }
@@ -1623,9 +1626,16 @@ make_weak_list (enum weak_list_type type)
   return result;
 }
 
+static const struct lrecord_description weak_list_description[] = {
+  { XD_LISP_OBJECT, offsetof (struct weak_list, list) },
+  { XD_LO_LINK,     offsetof (struct weak_list, next_weak) },
+  { XD_END }
+};
+
 DEFINE_LRECORD_IMPLEMENTATION ("weak-list", weak_list,
                               mark_weak_list, print_weak_list,
                               0, weak_list_equal, weak_list_hash,
+                              weak_list_description,
                               struct weak_list);
 /*
    -- we do not mark the list elements (either the elements themselves
@@ -1645,20 +1655,19 @@ DEFINE_LRECORD_IMPLEMENTATION ("weak-list", weak_list,
 */
 
 int
-finish_marking_weak_lists (int (*obj_marked_p) (Lisp_Object),
-                          void (*markobj) (Lisp_Object))
+finish_marking_weak_lists (void)
 {
   Lisp_Object rest;
   int did_mark = 0;
 
   for (rest = Vall_weak_lists;
-       !GC_NILP (rest);
+       !NILP (rest);
        rest = XWEAK_LIST (rest)->next_weak)
     {
       Lisp_Object rest2;
       enum weak_list_type type = XWEAK_LIST (rest)->type;
 
-      if (! obj_marked_p (rest))
+      if (! marked_p (rest))
        /* The weak list is probably garbage.  Ignore it. */
        continue;
 
@@ -1666,7 +1675,7 @@ finish_marking_weak_lists (int (*obj_marked_p) (Lisp_Object),
           /* We need to be trickier since we're inside of GC;
              use CONSP instead of !NILP in case of user-visible
              imperfect lists */
-          GC_CONSP (rest2);
+          CONSP (rest2);
           rest2 = XCDR (rest2))
        {
          Lisp_Object elem;
@@ -1681,7 +1690,7 @@ finish_marking_weak_lists (int (*obj_marked_p) (Lisp_Object),
             (either because of an external pointer or because of
             a previous call to this function), and likewise for all
             the rest of the elements in the list, so we can stop now. */
-         if (obj_marked_p (rest2))
+         if (marked_p (rest2))
            break;
 
          elem = XCAR (rest2);
@@ -1689,19 +1698,19 @@ finish_marking_weak_lists (int (*obj_marked_p) (Lisp_Object),
          switch (type)
            {
            case WEAK_LIST_SIMPLE:
-             if (obj_marked_p (elem))
+             if (marked_p (elem))
                need_to_mark_cons = 1;
              break;
 
            case WEAK_LIST_ASSOC:
-             if (!GC_CONSP (elem))
+             if (!CONSP (elem))
                {
                  /* just leave bogus elements there */
                  need_to_mark_cons = 1;
                  need_to_mark_elem = 1;
                }
-             else if (obj_marked_p (XCAR (elem)) &&
-                      obj_marked_p (XCDR (elem)))
+             else if (marked_p (XCAR (elem)) &&
+                      marked_p (XCDR (elem)))
                {
                  need_to_mark_cons = 1;
                  /* We still need to mark elem, because it's
@@ -1711,13 +1720,13 @@ finish_marking_weak_lists (int (*obj_marked_p) (Lisp_Object),
              break;
 
            case WEAK_LIST_KEY_ASSOC:
-             if (!GC_CONSP (elem))
+             if (!CONSP (elem))
                {
                  /* just leave bogus elements there */
                  need_to_mark_cons = 1;
                  need_to_mark_elem = 1;
                }
-             else if (obj_marked_p (XCAR (elem)))
+             else if (marked_p (XCAR (elem)))
                {
                  need_to_mark_cons = 1;
                  /* We still need to mark elem and XCDR (elem);
@@ -1727,13 +1736,30 @@ finish_marking_weak_lists (int (*obj_marked_p) (Lisp_Object),
              break;
 
            case WEAK_LIST_VALUE_ASSOC:
-             if (!GC_CONSP (elem))
+             if (!CONSP (elem))
+               {
+                 /* just leave bogus elements there */
+                 need_to_mark_cons = 1;
+                 need_to_mark_elem = 1;
+               }
+             else if (marked_p (XCDR (elem)))
+               {
+                 need_to_mark_cons = 1;
+                 /* We still need to mark elem and XCAR (elem);
+                    marking elem does both */
+                 need_to_mark_elem = 1;
+               }
+             break;
+
+           case WEAK_LIST_FULL_ASSOC:
+             if (!CONSP (elem))
                {
                  /* just leave bogus elements there */
                  need_to_mark_cons = 1;
                  need_to_mark_elem = 1;
                }
-             else if (obj_marked_p (XCDR (elem)))
+             else if (marked_p (XCAR (elem)) ||
+                      marked_p (XCDR (elem)))
                {
                  need_to_mark_cons = 1;
                  /* We still need to mark elem and XCAR (elem);
@@ -1746,23 +1772,23 @@ finish_marking_weak_lists (int (*obj_marked_p) (Lisp_Object),
              abort ();
            }
 
-         if (need_to_mark_elem && ! obj_marked_p (elem))
+         if (need_to_mark_elem && ! marked_p (elem))
            {
-             markobj (elem);
+             mark_object (elem);
              did_mark = 1;
            }
 
          /* We also need to mark the cons that holds the elem or
-            assoc-pair.  We do *not* want to call (markobj) here
+            assoc-pair.  We do *not* want to call (mark_object) here
             because that will mark the entire list; we just want to
             mark the cons itself.
             */
          if (need_to_mark_cons)
            {
-             struct Lisp_Cons *ptr = XCONS (rest2);
-             if (!CONS_MARKED_P (ptr))
+             Lisp_Cons *c = XCONS (rest2);
+             if (!CONS_MARKED_P (c))
                {
-                 MARK_CONS (ptr);
+                 MARK_CONS (c);
                  did_mark = 1;
                }
            }
@@ -1770,9 +1796,9 @@ finish_marking_weak_lists (int (*obj_marked_p) (Lisp_Object),
 
       /* In case of imperfect list, need to mark the final cons
          because we're not removing it */
-      if (!GC_NILP (rest2) && ! obj_marked_p (rest2))
+      if (!NILP (rest2) && ! marked_p (rest2))
        {
-         markobj (rest2);
+         mark_object (rest2);
          did_mark = 1;
        }
     }
@@ -1781,18 +1807,18 @@ finish_marking_weak_lists (int (*obj_marked_p) (Lisp_Object),
 }
 
 void
-prune_weak_lists (int (*obj_marked_p) (Lisp_Object))
+prune_weak_lists (void)
 {
   Lisp_Object rest, prev = Qnil;
 
   for (rest = Vall_weak_lists;
-       !GC_NILP (rest);
+       !NILP (rest);
        rest = XWEAK_LIST (rest)->next_weak)
     {
-      if (! (obj_marked_p (rest)))
+      if (! (marked_p (rest)))
        {
          /* This weak list itself is garbage.  Remove it from the list. */
-         if (GC_NILP (prev))
+         if (NILP (prev))
            Vall_weak_lists = XWEAK_LIST (rest)->next_weak;
          else
            XWEAK_LIST (prev)->next_weak =
@@ -1808,7 +1834,7 @@ prune_weak_lists (int (*obj_marked_p) (Lisp_Object))
               /* We need to be trickier since we're inside of GC;
                  use CONSP instead of !NILP in case of user-visible
                  imperfect lists */
-              GC_CONSP (rest2);)
+              CONSP (rest2);)
            {
              /* It suffices to check the cons for marking,
                 regardless of the type of weak list:
@@ -1819,10 +1845,10 @@ prune_weak_lists (int (*obj_marked_p) (Lisp_Object))
                    have been marked in finish_marking_weak_lists().
                 -- otherwise, it's not marked and should disappear.
                 */
-             if (! obj_marked_p (rest2))
+             if (! marked_p (rest2))
                {
                  /* bye bye :-( */
-                 if (GC_NILP (prev2))
+                 if (NILP (prev2))
                    XWEAK_LIST (rest)->list = XCDR (rest2);
                  else
                    XCDR (prev2) = XCDR (rest2);
@@ -1863,7 +1889,7 @@ prune_weak_lists (int (*obj_marked_p) (Lisp_Object))
                  if (go_tortoise)
                    tortoise = XCDR (tortoise);
                  go_tortoise = !go_tortoise;
-                 if (GC_EQ (rest2, tortoise))
+                 if (EQ (rest2, tortoise))
                    break;
                }
            }
@@ -1882,6 +1908,7 @@ decode_weak_list_type (Lisp_Object symbol)
   if (EQ (symbol, Qold_assoc))  return WEAK_LIST_ASSOC;  /* EBOLA ALERT! */
   if (EQ (symbol, Qkey_assoc))  return WEAK_LIST_KEY_ASSOC;
   if (EQ (symbol, Qvalue_assoc)) return WEAK_LIST_VALUE_ASSOC;
+  if (EQ (symbol, Qfull_assoc))  return WEAK_LIST_FULL_ASSOC;
 
   signal_simple_error ("Invalid weak list type", symbol);
   return WEAK_LIST_SIMPLE; /* not reached */
@@ -1896,6 +1923,7 @@ encode_weak_list_type (enum weak_list_type type)
     case WEAK_LIST_ASSOC:       return Qassoc;
     case WEAK_LIST_KEY_ASSOC:   return Qkey_assoc;
     case WEAK_LIST_VALUE_ASSOC: return Qvalue_assoc;
+    case WEAK_LIST_FULL_ASSOC:  return Qfull_assoc;
     default:
       abort ();
     }
@@ -1934,6 +1962,8 @@ to `simple'.  Recognized types are
                and the car is not pointed to.
 `value-assoc'  Objects in the list disappear if they are conses
                and the cdr is not pointed to.
+`full-assoc'   Objects in the list disappear if they are conses
+               and neither the car nor the cdr is pointed to.
 */
        (type))
 {
@@ -2004,8 +2034,8 @@ init_data_very_early (void)
 void
 init_errors_once_early (void)
 {
-  defsymbol (&Qerror_conditions, "error-conditions");
-  defsymbol (&Qerror_message, "error-message");
+  DEFSYMBOL (Qerror_conditions);
+  DEFSYMBOL (Qerror_message);
 
   /* We declare the errors here because some other deferrors depend
      on some of the errors below. */
@@ -2013,101 +2043,100 @@ init_errors_once_early (void)
   /* ERROR is used as a signaler for random errors for which nothing
      else is right */
 
-  deferror (&Qerror, "error", "error", Qnil);
-  deferror (&Qquit, "quit", "Quit", Qnil);
+  DEFERROR (Qerror, "error", Qnil);
+  DEFERROR_STANDARD (Qquit, Qnil);
 
-  deferror (&Qwrong_type_argument, "wrong-type-argument",
-           "Wrong type argument", Qerror);
-  deferror (&Qargs_out_of_range, "args-out-of-range", "Args out of range",
-           Qerror);
-  deferror (&Qvoid_function, "void-function",
-           "Symbol's function definition is void", Qerror);
-  deferror (&Qcyclic_function_indirection, "cyclic-function-indirection",
-           "Symbol's chain of function indirections contains a loop", Qerror);
-  deferror (&Qvoid_variable, "void-variable",
-           "Symbol's value as variable is void", Qerror);
-  deferror (&Qcyclic_variable_indirection, "cyclic-variable-indirection",
-           "Symbol's chain of variable indirections contains a loop", Qerror);
-  deferror (&Qsetting_constant, "setting-constant",
-           "Attempt to set a constant symbol", Qerror);
-  deferror (&Qinvalid_read_syntax, "invalid-read-syntax",
-           "Invalid read syntax", Qerror);
+  DEFERROR (Qunimplemented, "Feature not yet implemented", Qerror);
+  DEFERROR_STANDARD (Qsyntax_error, Qerror);
+  DEFERROR_STANDARD (Qinvalid_read_syntax, Qsyntax_error);
+  DEFERROR_STANDARD (Qlist_formation_error, Qsyntax_error);
 
   /* Generated by list traversal macros */
-  deferror (&Qmalformed_list, "malformed-list",
-           "Malformed list", Qerror);
-  deferror (&Qmalformed_property_list, "malformed-property-list",
-           "Malformed property list", Qmalformed_list);
-  deferror (&Qcircular_list, "circular-list",
-           "Circular list", Qerror);
-  deferror (&Qcircular_property_list, "circular-property-list",
-           "Circular property list", Qcircular_list);
-
-  deferror (&Qinvalid_function, "invalid-function", "Invalid function",
-           Qerror);
-  deferror (&Qwrong_number_of_arguments, "wrong-number-of-arguments",
-           "Wrong number of arguments", Qerror);
-  deferror (&Qno_catch, "no-catch", "No catch for tag",
-           Qerror);
-  deferror (&Qbeginning_of_buffer, "beginning-of-buffer",
-           "Beginning of buffer", Qerror);
-  deferror (&Qend_of_buffer, "end-of-buffer", "End of buffer", Qerror);
-  deferror (&Qbuffer_read_only, "buffer-read-only", "Buffer is read-only",
-           Qerror);
+  DEFERROR_STANDARD (Qmalformed_list, Qlist_formation_error);
+  DEFERROR_STANDARD (Qmalformed_property_list, Qmalformed_list);
+  DEFERROR_STANDARD (Qcircular_list, Qlist_formation_error);
+  DEFERROR_STANDARD (Qcircular_property_list, Qcircular_list);
+
+  DEFERROR_STANDARD (Qinvalid_argument, Qerror);
+  DEFERROR_STANDARD (Qwrong_type_argument, Qinvalid_argument);
+  DEFERROR_STANDARD (Qargs_out_of_range, Qinvalid_argument);
+  DEFERROR_STANDARD (Qwrong_number_of_arguments, Qinvalid_argument);
+  DEFERROR_STANDARD (Qinvalid_function, Qinvalid_argument);
+  DEFERROR (Qno_catch, "No catch for tag", Qinvalid_argument);
 
-  deferror (&Qio_error, "io-error", "IO Error", Qerror);
-  deferror (&Qend_of_file, "end-of-file", "End of stream", Qio_error);
+  DEFERROR_STANDARD (Qinternal_error, Qerror);
 
-  deferror (&Qarith_error, "arith-error", "Arithmetic error", Qerror);
-  deferror (&Qrange_error, "range-error", "Arithmetic range error",
-           Qarith_error);
-  deferror (&Qdomain_error, "domain-error", "Arithmetic domain error",
-           Qarith_error);
-  deferror (&Qsingularity_error, "singularity-error",
-           "Arithmetic singularity error", Qdomain_error);
-  deferror (&Qoverflow_error, "overflow-error",
-           "Arithmetic overflow error", Qdomain_error);
-  deferror (&Qunderflow_error, "underflow-error",
-           "Arithmetic underflow error", Qdomain_error);
+  DEFERROR (Qinvalid_state, "Properties or values have been set incorrectly",
+           Qerror);
+  DEFERROR (Qvoid_function, "Symbol's function definition is void",
+           Qinvalid_state);
+  DEFERROR (Qcyclic_function_indirection,
+           "Symbol's chain of function indirections contains a loop",
+           Qinvalid_state);
+  DEFERROR (Qvoid_variable, "Symbol's value as variable is void",
+           Qinvalid_state);
+  DEFERROR (Qcyclic_variable_indirection,
+           "Symbol's chain of variable indirections contains a loop",
+           Qinvalid_state);
+
+  DEFERROR (Qinvalid_operation,
+           "Operation not allowed or error during operation", Qerror);
+  DEFERROR (Qinvalid_change, "Attempt to set properties or values incorrectly",
+           Qinvalid_operation);
+  DEFERROR (Qsetting_constant, "Attempt to set a constant symbol",
+           Qinvalid_change);
+
+  DEFERROR (Qediting_error, "Invalid operation during editing",
+           Qinvalid_operation);
+  DEFERROR_STANDARD (Qbeginning_of_buffer, Qediting_error);
+  DEFERROR_STANDARD (Qend_of_buffer, Qediting_error);
+  DEFERROR (Qbuffer_read_only, "Buffer is read-only", Qediting_error);
+
+  DEFERROR (Qio_error, "IO Error", Qinvalid_operation);
+  DEFERROR (Qend_of_file, "End of file or stream", Qio_error);
+
+  DEFERROR (Qarith_error, "Arithmetic error", Qinvalid_operation);
+  DEFERROR (Qrange_error, "Arithmetic range error", Qarith_error);
+  DEFERROR (Qdomain_error, "Arithmetic domain error", Qarith_error);
+  DEFERROR (Qsingularity_error, "Arithmetic singularity error", Qdomain_error);
+  DEFERROR (Qoverflow_error, "Arithmetic overflow error", Qdomain_error);
+  DEFERROR (Qunderflow_error, "Arithmetic underflow error", Qdomain_error);
 }
 
 void
 syms_of_data (void)
 {
-  defsymbol (&Qcons, "cons");
-  defsymbol (&Qkeyword, "keyword");
-  defsymbol (&Qquote, "quote");
-  defsymbol (&Qlambda, "lambda");
-  defsymbol (&Qignore, "ignore");
-  defsymbol (&Qlistp, "listp");
-  defsymbol (&Qtrue_list_p, "true-list-p");
-  defsymbol (&Qconsp, "consp");
-  defsymbol (&Qsubrp, "subrp");
-  defsymbol (&Qsymbolp, "symbolp");
-  defsymbol (&Qkeywordp, "keywordp");
-  defsymbol (&Qintegerp, "integerp");
-  defsymbol (&Qcharacterp, "characterp");
-  defsymbol (&Qnatnump, "natnump");
-  defsymbol (&Qstringp, "stringp");
-  defsymbol (&Qarrayp, "arrayp");
-  defsymbol (&Qsequencep, "sequencep");
-  defsymbol (&Qbufferp, "bufferp");
-  defsymbol (&Qbitp, "bitp");
-  defsymbol (&Qbit_vectorp, "bit-vector-p");
-  defsymbol (&Qvectorp, "vectorp");
-  defsymbol (&Qchar_or_string_p, "char-or-string-p");
-  defsymbol (&Qmarkerp, "markerp");
-  defsymbol (&Qinteger_or_marker_p, "integer-or-marker-p");
-  defsymbol (&Qinteger_or_char_p, "integer-or-char-p");
-  defsymbol (&Qinteger_char_or_marker_p, "integer-char-or-marker-p");
-  defsymbol (&Qnumberp, "numberp");
-  defsymbol (&Qnumber_or_marker_p, "number-or-marker-p");
-  defsymbol (&Qnumber_char_or_marker_p, "number-char-or-marker-p");
-  defsymbol (&Qcdr, "cdr");
-  defsymbol (&Qweak_listp, "weak-list-p");
+  INIT_LRECORD_IMPLEMENTATION (weak_list);
+
+  DEFSYMBOL (Qquote);
+  DEFSYMBOL (Qlambda);
+  DEFSYMBOL (Qlistp);
+  DEFSYMBOL (Qtrue_list_p);
+  DEFSYMBOL (Qconsp);
+  DEFSYMBOL (Qsubrp);
+  DEFSYMBOL (Qsymbolp);
+  DEFSYMBOL (Qintegerp);
+  DEFSYMBOL (Qcharacterp);
+  DEFSYMBOL (Qnatnump);
+  DEFSYMBOL (Qstringp);
+  DEFSYMBOL (Qarrayp);
+  DEFSYMBOL (Qsequencep);
+  DEFSYMBOL (Qbufferp);
+  DEFSYMBOL (Qbitp);
+  DEFSYMBOL_MULTIWORD_PREDICATE (Qbit_vectorp);
+  DEFSYMBOL (Qvectorp);
+  DEFSYMBOL (Qchar_or_string_p);
+  DEFSYMBOL (Qmarkerp);
+  DEFSYMBOL (Qinteger_or_marker_p);
+  DEFSYMBOL (Qinteger_or_char_p);
+  DEFSYMBOL (Qinteger_char_or_marker_p);
+  DEFSYMBOL (Qnumberp);
+  DEFSYMBOL (Qnumber_char_or_marker_p);
+  DEFSYMBOL (Qcdr);
+  DEFSYMBOL_MULTIWORD_PREDICATE (Qweak_listp);
 
 #ifdef LISP_FLOAT_TYPE
-  defsymbol (&Qfloatp, "floatp");
+  DEFSYMBOL (Qfloatp);
 #endif /* LISP_FLOAT_TYPE */
 
   DEFSUBR (Fwrong_type_argument);
@@ -2200,6 +2229,7 @@ vars_of_data (void)
 {
   /* This must not be staticpro'd */
   Vall_weak_lists = Qnil;
+  pdump_wire_list (&Vall_weak_lists);
 
 #ifdef DEBUG_XEMACS
   DEFVAR_BOOL ("debug-issue-ebola-notices", &debug_issue_ebola_notices /*