diff src/data.c @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children 0293115a14e9
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/data.c	Mon Aug 13 08:45:50 2007 +0200
@@ -0,0 +1,2307 @@
+/* Primitive operations on Lisp data types for XEmacs Lisp interpreter.
+   Copyright (C) 1985, 1986, 1988, 1992, 1993, 1994, 1995
+   Free Software Foundation, Inc.
+
+This file is part of XEmacs.
+
+XEmacs is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with XEmacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Synched up with: Mule 2.0, FSF 19.30.  Some of FSF's data.c is in
+   XEmacs' symbols.c. */
+
+/* This file has been Mule-ized. */
+
+#include <config.h>
+#include "lisp.h"
+
+#include "buffer.h"
+#include "bytecode.h"
+
+#include "syssignal.h"
+#ifdef LISP_FLOAT_TYPE
+/* Need to define a differentiating symbol -- see sysfloat.h */
+# define THIS_FILENAME data_c
+# include "sysfloat.h"
+#endif /* LISP_FLOAT_TYPE */
+
+Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound;
+Lisp_Object Qerror_conditions, Qerror_message, Qtop_level;
+Lisp_Object Qsignal, 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 Qmalformed_list, Qmalformed_property_list;
+Lisp_Object Qcircular_list, Qcircular_property_list;
+Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch;
+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, Qlistp, Qconsp, Qsubrp;
+Lisp_Object Qcharacterp, Qstringp, Qarrayp, Qsequencep, Qbufferp;
+Lisp_Object Qcompiled_functionp;
+Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp;
+Lisp_Object Qinteger_or_char_p, Qinteger_char_or_marker_p;
+Lisp_Object Qbit_vectorp, Qbitp;
+
+/* Qstring, Qinteger, Qsymbol, Qvector defined in general.c */
+Lisp_Object Qcons, Qkeyword;
+
+Lisp_Object Qcdr;
+
+Lisp_Object Qignore;
+
+#ifdef LISP_FLOAT_TYPE
+Lisp_Object Qfloatp;
+#endif
+Lisp_Object Qnumberp, Qnumber_or_marker_p, Qnumber_char_or_marker_p;
+
+Lisp_Object Qweak_listp;
+
+Lisp_Object
+wrong_type_argument (Lisp_Object predicate, Lisp_Object value)
+{
+  /* This function can GC */
+  REGISTER Lisp_Object tem;
+  do
+    {
+#ifdef MOCKLISP_SUPPORT
+      if (!EQ (Vmocklisp_arguments, Qt))
+	{
+	 if (STRINGP (value) &&
+	     (EQ (predicate, Qintegerp) ||
+	      EQ (predicate, Qinteger_or_marker_p) ||
+	      EQ (predicate, Qinteger_char_or_marker_p)))
+	   return Fstring_to_number (value);
+	 if (INTP (value) && EQ (predicate, Qstringp))
+	   return Fnumber_to_string (value);
+	 if (CHARP (value) && EQ (predicate, Qstringp))
+	   return Fchar_to_string (value);
+	}
+#endif
+      value = Fsignal (Qwrong_type_argument, list2 (predicate, value));
+      tem = call1 (predicate, value);
+    }
+  while (NILP (tem));
+  return value;
+}
+
+DOESNT_RETURN
+dead_wrong_type_argument (Lisp_Object predicate, Lisp_Object value)
+{
+  signal_error (Qwrong_type_argument, list2 (predicate, value));
+}
+
+DEFUN ("wrong-type-argument", Fwrong_type_argument, Swrong_type_argument,
+       2, 2, 0 /*
+Signal an error until the correct type value is given by the user.
+This function loops, signalling a continuable `wrong-type-argument' error
+with PREDICATE and VALUE as the data associated with the error and then
+calling PREDICATE on the returned value, until the value gotten satisfies
+PREDICATE.  At that point, the gotten value is returned.
+*/ )
+  (predicate, value)
+     Lisp_Object predicate, value;
+{
+  return wrong_type_argument (predicate, value);
+}
+
+DOESNT_RETURN
+pure_write_error (void)
+{
+  error ("Attempt to modify read-only object");
+}
+
+DOESNT_RETURN
+args_out_of_range (Lisp_Object a1, Lisp_Object a2)
+{
+  signal_error (Qargs_out_of_range, list2 (a1, a2));
+}
+
+DOESNT_RETURN
+args_out_of_range_3 (Lisp_Object a1, Lisp_Object a2, Lisp_Object a3)
+{
+  signal_error (Qargs_out_of_range, list3 (a1, a2, a3));
+}
+
+void
+check_int_range (int val, int min, int max)
+{
+  if (val < min || val > max)
+    args_out_of_range_3 (make_int (val), make_int (min),
+			 make_int (max));
+}
+
+#ifndef make_int
+Lisp_Object
+make_int (EMACS_INT num)
+{
+  Lisp_Object val;
+  /* Don't use XSETINT here -- it's defined in terms of make_int ().  */
+  XSETOBJ (val, Lisp_Int, num);
+  return val;
+}
+#endif /* ! defined (make_int) */
+
+/* On some machines, XINT needs a temporary location.
+   Here it is, in case it is needed.  */
+
+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
+sign_extend_lisp_int (EMACS_INT num)
+{
+  if (num & (1L << (VALBITS - 1)))
+    return num | ((-1L) << VALBITS);
+  else
+    return num & ((1L << VALBITS) - 1);
+}
+
+/* characters do not need to sign extend so there's no need for special
+   futzing like with ints. */
+Lisp_Object
+make_char (Emchar num)
+{
+  return make_int (num);
+}
+
+/* Data type predicates */
+
+DEFUN ("eq", Feq, Seq, 2, 2, 0 /*
+T if the two args are the same Lisp object.
+*/ )
+  (obj1, obj2)
+     Lisp_Object obj1, obj2;
+{
+  if (EQ (obj1, obj2))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("null", Fnull, Snull, 1, 1, 0 /*
+T if OBJECT is nil.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (NILP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("consp", Fconsp, Sconsp, 1, 1, 0 /*
+T if OBJECT is a cons cell.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (CONSP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("atom", Fatom, Satom, 1, 1, 0 /*
+T if OBJECT is not a cons cell.  This includes nil.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (CONSP (object))
+    return Qnil;
+  return Qt;
+}
+
+DEFUN ("listp", Flistp, Slistp, 1, 1, 0 /*
+T if OBJECT is a list.  This includes nil.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (CONSP (object) || NILP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("nlistp", Fnlistp, Snlistp, 1, 1, 0 /*
+T if OBJECT is not a list.  Lists include nil.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (CONSP (object) || NILP (object))
+    return Qnil;
+  return Qt;
+}
+
+DEFUN ("symbolp", Fsymbolp, Ssymbolp, 1, 1, 0 /*
+T if OBJECT is a symbol.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (SYMBOLP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("keywordp", Fkeywordp, Skeywordp, 1, 1, 0 /*
+T if OBJECT is a keyword.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (KEYWORDP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("vectorp", Fvectorp, Svectorp, 1, 1, 0 /*
+T if OBJECT is a vector.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (VECTORP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("bit-vector-p", Fbit_vector_p, Sbit_vector_p, 1, 1, 0 /*
+T if OBJECT is a bit vector.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (BIT_VECTORP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("stringp", Fstringp, Sstringp, 1, 1, 0 /*
+T if OBJECT is a string.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (STRINGP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("arrayp", Farrayp, Sarrayp, 1, 1, 0 /*
+T if OBJECT is an array (string, vector, or bit vector).
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (VECTORP (object) || STRINGP (object) || BIT_VECTORP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("sequencep", Fsequencep, Ssequencep, 1, 1, 0 /*
+T if OBJECT is a sequence (list or array).
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (CONSP (object) || NILP (object) 
+      || VECTORP (object) || STRINGP (object) || BIT_VECTORP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("markerp", Fmarkerp, Smarkerp, 1, 1, 0 /*
+T if OBJECT is a marker (editor pointer).
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (MARKERP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("subrp", Fsubrp, Ssubrp, 1, 1, 0 /*
+T if OBJECT is a built-in function.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (SUBRP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("subr-min-args", Fsubr_min_args, Ssubr_min_args, 1, 1, 0 /*
+Return minimum number of args built-in function SUBR may be called with.
+*/ )
+  (subr)
+     Lisp_Object subr;
+{
+  CHECK_SUBR (subr);
+  return make_int (XSUBR (subr)->min_args);
+}
+
+DEFUN ("subr-max-args", Fsubr_max_args, Ssubr_max_args, 1, 1, 0 /*
+Return maximum number of args built-in function SUBR may be called with,
+or nil if it takes an arbitrary number of arguments (or is a special form).
+*/ )
+  (subr)
+     Lisp_Object subr;
+{
+  int nargs;
+  CHECK_SUBR (subr);
+  nargs = XSUBR (subr)->max_args;
+  if (nargs == MANY || nargs == UNEVALLED)
+    return Qnil;
+  else
+    return make_int (nargs);
+}
+
+DEFUN ("compiled-function-p", Fcompiled_function_p, Scompiled_function_p, 1, 1, 0 /*
+t if OBJECT is a byte-compiled function object.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (COMPILED_FUNCTIONP (object))
+    return Qt;
+  return Qnil;
+}
+
+
+DEFUN ("characterp", Fcharacterp, Scharacterp, 1, 1, 0 /*
+t if OBJECT is a character.
+A character is an integer that can be inserted into a buffer with
+`insert-char'.  All integers are considered valid characters and are
+modded with 256 to get the actual character to use.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (CHARP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("char-or-string-p", Fchar_or_string_p, Schar_or_string_p, 1, 1, 0 /*
+t if OBJECT is a character or a string.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (CHAR_OR_CHAR_INTP (object) || STRINGP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("integerp", Fintegerp, Sintegerp, 1, 1, 0 /*
+t if OBJECT is an integer.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (INTP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("integer-or-marker-p", Finteger_or_marker_p, Sinteger_or_marker_p,
+       1, 1, 0 /*
+t if OBJECT is an integer or a marker (editor pointer).
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (INTP (object) || MARKERP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("natnump", Fnatnump, Snatnump, 1, 1, 0 /*
+t if OBJECT is a nonnegative integer.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (NATNUMP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("bitp", Fbitp, Sbitp, 1, 1, 0 /*
+t if OBJECT is a bit (0 or 1).
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (BITP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("numberp", Fnumberp, Snumberp, 1, 1, 0 /*
+t if OBJECT is a number (floating point or integer).
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (INT_OR_FLOATP (object))
+    return Qt;
+  return Qnil;
+}
+
+DEFUN ("number-or-marker-p", Fnumber_or_marker_p, Snumber_or_marker_p, 1, 1, 0 /*
+t if OBJECT is a number or a marker.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (INT_OR_FLOATP (object)
+      || MARKERP (object))
+    return Qt;
+  return Qnil;
+}
+
+#ifdef LISP_FLOAT_TYPE
+DEFUN ("floatp", Ffloatp, Sfloatp, 1, 1, 0 /*
+t if OBJECT is a floating point number.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (FLOATP (object))
+    return Qt;
+  return Qnil;
+}
+#endif /* LISP_FLOAT_TYPE */
+
+DEFUN ("type-of", Ftype_of, Stype_of, 1, 1, 0 /*
+Return a symbol representing the type of OBJECT.
+*/ )
+  (object)
+    Lisp_Object object;
+{
+  if (CONSP (object))
+    return Qcons;
+  if (SYMBOLP (object))
+    return Qsymbol;
+  if (KEYWORDP (object))
+    return Qkeyword;
+  if (INTP (object))
+    return Qinteger;
+  if (STRINGP (object))
+    return Qstring;
+  if (VECTORP (object))
+    return Qvector;
+  assert (LRECORDP (object));
+  return intern (XRECORD_LHEADER (object)->implementation->name);
+}
+
+
+/* Extract and set components of lists */
+
+DEFUN ("car", Fcar, Scar, 1, 1, 0 /*
+Return the car of LIST.  If arg is nil, return nil.
+Error if arg is not nil and not a cons cell.  See also `car-safe'.
+*/ )
+  (list)
+     Lisp_Object list;
+{
+  while (1)
+    {
+      if (CONSP (list))
+	return XCAR (list);
+      else if (NILP (list))
+	return Qnil;
+      else
+	list = wrong_type_argument (Qconsp, list);
+    }
+}
+
+DEFUN ("car-safe", Fcar_safe, Scar_safe, 1, 1, 0 /*
+Return the car of OBJECT if it is a cons cell, or else nil.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (CONSP (object))
+    return XCAR (object);
+  else
+    return Qnil;
+}
+
+DEFUN ("cdr", Fcdr, Scdr, 1, 1, 0 /*
+Return the cdr of LIST.  If arg is nil, return nil.
+Error if arg is not nil and not a cons cell.  See also `cdr-safe'.
+*/ )
+  (list)
+     Lisp_Object list;
+{
+  while (1)
+    {
+      if (CONSP (list))
+	return XCDR (list);
+      else if (NILP (list))
+	return Qnil;
+      else
+	list = wrong_type_argument (Qconsp, list);
+    }
+}
+
+DEFUN ("cdr-safe", Fcdr_safe, Scdr_safe, 1, 1, 0 /*
+Return the cdr of OBJECT if it is a cons cell, or else  nil.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  if (CONSP (object))
+    return XCDR (object);
+  else
+    return Qnil;
+}
+
+DEFUN ("setcar", Fsetcar, Ssetcar, 2, 2, 0 /*
+Set the car of CONSCELL to be NEWCAR.  Returns NEWCAR.
+*/ )
+  (conscell, newcar)
+     Lisp_Object conscell, newcar;
+{
+  if (!CONSP (conscell))
+    conscell = wrong_type_argument (Qconsp, conscell);
+
+  CHECK_IMPURE (conscell);
+  XCAR (conscell) = newcar;
+  return newcar;
+}
+
+DEFUN ("setcdr", Fsetcdr, Ssetcdr, 2, 2, 0 /*
+Set the cdr of CONSCELL to be NEWCDR.  Returns NEWCDR.
+*/ )
+  (conscell, newcdr)
+     Lisp_Object conscell, newcdr;
+{
+  if (!CONSP (conscell))
+    conscell = wrong_type_argument (Qconsp, conscell);
+
+  CHECK_IMPURE (conscell);
+  XCDR (conscell) = newcdr;
+  return newcdr;
+}
+
+/* Find the function at the end of a chain of symbol function indirections.  */
+
+/* If OBJECT is a symbol, find the end of its function chain and
+   return the value found there.  If OBJECT is not a symbol, just
+   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.  */
+Lisp_Object
+indirect_function (Lisp_Object object, int errorp)
+{
+  Lisp_Object tortoise = object; 
+  Lisp_Object hare = object;
+
+  for (;;)
+    {
+      if (!SYMBOLP (hare) || UNBOUNDP (hare))
+	break;
+      hare = XSYMBOL (hare)->function;
+      if (!SYMBOLP (hare) || UNBOUNDP (hare))
+	break;
+      hare = XSYMBOL (hare)->function;
+
+      tortoise = XSYMBOL (tortoise)->function;
+
+      if (EQ (hare, tortoise))
+	return (Fsignal (Qcyclic_function_indirection, list1 (object)));
+    }
+
+  if (UNBOUNDP (hare) && errorp)
+    return Fsignal (Qvoid_function, list1 (object));
+  return hare;
+}
+
+DEFUN ("indirect-function", Findirect_function, Sindirect_function, 1, 1, 0 /*
+Return the function at the end of OBJECT's function chain.
+If OBJECT is a symbol, follow all function indirections and return
+the final function binding.
+If OBJECT is not a symbol, just return it.
+Signal a void-function error if the final symbol is unbound.
+Signal a cyclic-function-indirection error if there is a loop in the
+function chain of symbols.
+*/ )
+  (object)
+    Lisp_Object object;
+{
+  return indirect_function (object, 1);
+}
+
+/* Extract and set vector and string elements */
+
+DEFUN ("aref", Faref, Saref, 2, 2, 0 /*
+Return the element of ARRAY at index INDEX.
+ARRAY may be a vector, bit vector, string, or byte-code object.
+IDX starts at 0.
+*/ )
+  (array, idx)
+     Lisp_Object array;
+     Lisp_Object idx;
+{
+  int idxval;
+
+ retry:
+  CHECK_INT_COERCE_CHAR (idx); /* yuck! */
+  idxval = XINT (idx);
+  if (idxval < 0)
+    {
+    lose:
+      args_out_of_range (array, idx);
+    }
+  if (VECTORP (array))
+    {
+      if (idxval >= vector_length (XVECTOR (array))) goto lose;
+      return vector_data (XVECTOR (array))[idxval];
+    }
+  else if (BIT_VECTORP (array))
+    {
+      if (idxval >= bit_vector_length (XBIT_VECTOR (array))) goto lose;
+      return make_int (bit_vector_bit (XBIT_VECTOR (array), idxval));
+    }
+  else if (STRINGP (array))
+    {
+      if (idxval >= string_char_length (XSTRING (array))) goto lose;
+      return (make_char (string_char (XSTRING (array), idxval)));
+    }
+#ifdef LOSING_BYTECODE
+  else if (COMPILED_FUNCTIONP (array))
+    {
+      /* Weird, gross compatibility kludge */
+      return (Felt (array, idx));
+    }
+#endif
+  else
+    {
+      check_losing_bytecode ("aref", array);
+      array = wrong_type_argument (Qarrayp, array);
+      goto retry;
+    }
+}
+
+DEFUN ("aset", Faset, Saset, 3, 3, 0 /*
+Store into the element of ARRAY at index IDX the value NEWVAL.
+ARRAY may be a vector, bit vector, or string.  IDX starts at 0.
+*/ )
+  (array, idx, newval)
+     Lisp_Object array;
+     Lisp_Object idx, newval;
+{
+  int idxval;
+
+  CHECK_INT_COERCE_CHAR (idx); /* yuck! */
+  if (!VECTORP (array) && !BIT_VECTORP (array) && !STRINGP (array))
+    array = wrong_type_argument (Qarrayp, array);
+
+  idxval = XINT (idx);
+  if (idxval < 0)
+    {
+    lose:
+      args_out_of_range (array, idx);
+    }
+  CHECK_IMPURE (array);
+
+  if (VECTORP (array))
+    {
+      if (idxval >= vector_length (XVECTOR (array))) goto lose;
+      vector_data (XVECTOR (array))[idxval] = newval;
+    }
+  else if (BIT_VECTORP (array))
+    {
+      if (idxval >= bit_vector_length (XBIT_VECTOR (array))) goto lose;
+      CHECK_BIT (newval);
+      set_bit_vector_bit (XBIT_VECTOR (array), idxval, !ZEROP (newval));
+    }
+  else                          /* string */
+    {
+      CHECK_CHAR_COERCE_INT (newval);
+      if (idxval >= string_char_length (XSTRING (array))) goto lose;
+      set_string_char (XSTRING (array), idxval, XCHAR (newval));
+      bump_string_modiff (array);
+    }
+
+  return newval;
+}
+
+
+/**********************************************************************/
+/*                      Compiled-function objects                     */
+/**********************************************************************/
+
+/* The compiled_function->doc_and_interactive slot uses the minimal
+   number of conses, based on compiled_function->flags; it may take
+   any of the following forms:
+
+	doc
+	interactive
+	domain
+	(doc . interactive)
+	(doc . domain)
+	(interactive . domain)
+	(doc . (interactive . domain))
+ */
+
+/* Caller must check flags.interactivep first */
+Lisp_Object
+compiled_function_interactive (struct Lisp_Compiled_Function *b)
+{
+  assert (b->flags.interactivep);
+  if (b->flags.documentationp && b->flags.domainp)
+    return (XCAR (XCDR (b->doc_and_interactive)));
+  else if (b->flags.documentationp)
+    return (XCDR (b->doc_and_interactive));
+  else if (b->flags.domainp)
+    return (XCAR (b->doc_and_interactive));
+
+  /* if all else fails... */
+  return (b->doc_and_interactive);
+}
+
+/* Caller need not check flags.documentationp first */
+Lisp_Object
+compiled_function_documentation (struct Lisp_Compiled_Function *b)
+{
+  if (! b->flags.documentationp)
+    return Qnil;
+  else if (b->flags.interactivep && b->flags.domainp)
+    return (XCAR (b->doc_and_interactive));
+  else if (b->flags.interactivep)
+    return (XCAR (b->doc_and_interactive));
+  else if (b->flags.domainp)
+    return (XCAR (b->doc_and_interactive));
+  else
+    return (b->doc_and_interactive);
+}
+
+/* Caller need not check flags.domainp first */
+Lisp_Object
+compiled_function_domain (struct Lisp_Compiled_Function *b)
+{
+  if (! b->flags.domainp)
+    return Qnil;
+  else if (b->flags.documentationp && b->flags.interactivep)
+    return (XCDR (XCDR (b->doc_and_interactive)));
+  else if (b->flags.documentationp)
+    return (XCDR (b->doc_and_interactive));
+  else if (b->flags.interactivep)
+    return (XCDR (b->doc_and_interactive));
+  else
+    return (b->doc_and_interactive);
+}
+
+#ifdef COMPILED_FUNCTION_ANNOTATION_HACK
+
+Lisp_Object
+compiled_function_annotation (struct Lisp_Compiled_Function *b)
+{
+  return b->annotated;
+}
+
+#endif
+
+/* used only by Snarf-documentation; there must be doc already. */
+void
+set_compiled_function_documentation (struct Lisp_Compiled_Function *b,
+				     Lisp_Object new)
+{
+  assert (b->flags.documentationp);
+  assert (INTP (new) || STRINGP (new));
+
+  if (b->flags.interactivep && b->flags.domainp)
+    XCAR (b->doc_and_interactive) = new;
+  else if (b->flags.interactivep)
+    XCAR (b->doc_and_interactive) = new;
+  else if (b->flags.domainp)
+    XCAR (b->doc_and_interactive) = new;
+  else
+    b->doc_and_interactive = new;
+}
+
+DEFUN ("compiled-function-instructions", Fcompiled_function_instructions,
+       Scompiled_function_instructions, 1, 1, 0 /*
+Return the byte-opcode string of the compiled-function object.
+*/ )
+     (function)
+     Lisp_Object function;
+{
+  CHECK_COMPILED_FUNCTION (function);
+  return (XCOMPILED_FUNCTION (function)->bytecodes);
+}
+
+DEFUN ("compiled-function-constants", Fcompiled_function_constants,
+       Scompiled_function_constants, 1, 1, 0 /*
+Return the constants vector of the compiled-function object.
+*/ )
+     (function)
+     Lisp_Object function;
+{
+  CHECK_COMPILED_FUNCTION (function);
+  return (XCOMPILED_FUNCTION (function)->constants);
+}
+
+DEFUN ("compiled-function-stack-depth", Fcompiled_function_stack_depth,
+       Scompiled_function_stack_depth, 1, 1, 0 /*
+Return the max stack depth of the compiled-function object.
+*/ )
+     (function)
+     Lisp_Object function;
+{
+  CHECK_COMPILED_FUNCTION (function);
+  return (make_int (XCOMPILED_FUNCTION (function)->maxdepth));
+}
+
+DEFUN ("compiled-function-arglist", Fcompiled_function_arglist,
+       Scompiled_function_arglist, 1, 1, 0 /*
+Return the argument list of the compiled-function object.
+*/ )
+     (function)
+     Lisp_Object function;
+{
+  CHECK_COMPILED_FUNCTION (function);
+  return (XCOMPILED_FUNCTION (function)->arglist);
+}
+
+DEFUN ("compiled-function-interactive", Fcompiled_function_interactive,
+       Scompiled_function_interactive, 1, 1, 0 /*
+Return the interactive spec of the compiled-function object, or nil.
+If non-nil, the return value will be a list whose first element is
+`interactive' and whose second element is the interactive spec.
+*/ )
+     (function)
+     Lisp_Object function;
+{
+  CHECK_COMPILED_FUNCTION (function);
+  if (!XCOMPILED_FUNCTION (function)->flags.interactivep)
+    return Qnil;
+  return (list2 (Qinteractive,
+		 compiled_function_interactive
+		 (XCOMPILED_FUNCTION (function))));
+}
+
+DEFUN ("compiled-function-doc-string", Fcompiled_function_doc_string,
+       Scompiled_function_doc_string, 1, 1, 0 /*
+Return the doc string of the compiled-function object, if available.
+*/ )
+     (function)
+     Lisp_Object function;
+{
+  CHECK_COMPILED_FUNCTION (function);
+  if (!XCOMPILED_FUNCTION (function)->flags.interactivep)
+    return Qnil;
+  return (list2 (Qinteractive,
+		 compiled_function_interactive
+		 (XCOMPILED_FUNCTION (function))));
+}
+
+#ifdef COMPILED_FUNCTION_ANNOTATION_HACK
+
+DEFUN ("compiled-function-annotation", Fcompiled_function_annotation,
+       Scompiled_function_annotation, 1, 1, 0 /*
+Return the annotation of the compiled-function object, or nil.
+The annotation is a piece of information indicating where this
+compiled-function object came from.  Generally this will be
+a symbol naming a function; or a string naming a file, if the
+compiled-function object was not defined in a function; or nil,
+if the compiled-function object was not created as a result of
+a `load'.
+*/ )
+     (function)
+     Lisp_Object function;
+{
+  CHECK_COMPILED_FUNCTION (function);
+  return (compiled_function_annotation (XCOMPILED_FUNCTION (function)));
+}
+
+#endif /* COMPILED_FUNCTION_ANNOTATION_HACK */
+
+DEFUN ("compiled-function-domain", Fcompiled_function_domain,
+       Scompiled_function_domain, 1, 1, 0 /*
+Return the domain of the compiled-function object, or nil.
+This is only meaningful if I18N3 was enabled when emacs was compiled.
+*/ )
+     (function)
+     Lisp_Object function;
+{
+  CHECK_COMPILED_FUNCTION (function);
+  if (!XCOMPILED_FUNCTION (function)->flags.domainp)
+    return Qnil;
+  return (compiled_function_domain (XCOMPILED_FUNCTION (function)));
+}
+
+
+/**********************************************************************/
+/*                       Arithmetic functions                         */
+/**********************************************************************/
+
+enum comparison { equal, notequal, less, grtr, less_or_equal, grtr_or_equal };
+
+static Lisp_Object
+arithcompare (Lisp_Object num1, Lisp_Object num2, 
+              enum comparison comparison)
+{
+  int floatp = 0;
+
+  CHECK_INT_OR_FLOAT_COERCE_CHAR_OR_MARKER (num1);
+  CHECK_INT_OR_FLOAT_COERCE_CHAR_OR_MARKER (num2);
+
+#ifdef LISP_FLOAT_TYPE
+  if (FLOATP (num1) || FLOATP (num2))
+    {
+      double f1, f2;
+
+      floatp = 1;
+      f1 = (FLOATP (num1)) ? float_data (XFLOAT (num1)) : XINT (num1);
+      f2 = (FLOATP (num2)) ? float_data (XFLOAT (num2)) : XINT (num2);
+
+      switch (comparison)
+        {
+        case equal:
+          if (f1 == f2)
+            return Qt;
+          return Qnil;
+
+        case notequal:
+          if (f1 != f2)
+            return Qt;
+          return Qnil;
+
+        case less:
+          if (f1 < f2)
+            return Qt;
+          return Qnil;
+
+        case less_or_equal:
+          if (f1 <= f2)
+            return Qt;
+          return Qnil;
+
+        case grtr:
+          if (f1 > f2)
+            return Qt;
+          return Qnil;
+
+        case grtr_or_equal:
+          if (f1 >= f2)
+            return Qt;
+          return Qnil;
+        }
+    }
+#endif /* LISP_FLOAT_TYPE */
+  else
+    {
+      switch (comparison)
+        {
+        case equal:
+          if (XINT (num1) == XINT (num2))
+            return Qt;
+          return Qnil;
+
+        case notequal:
+          if (XINT (num1) != XINT (num2))
+            return Qt;
+          return Qnil;
+
+        case less:
+          if (XINT (num1) < XINT (num2))
+            return Qt;
+          return Qnil;
+
+        case less_or_equal:
+          if (XINT (num1) <= XINT (num2))
+            return Qt;
+          return Qnil;
+
+        case grtr:
+          if (XINT (num1) > XINT (num2))
+            return Qt;
+          return Qnil;
+
+        case grtr_or_equal:
+          if (XINT (num1) >= XINT (num2))
+            return Qt;
+          return Qnil;
+        }
+    }
+  abort ();
+  return Qnil;	/* suppress compiler warning */
+}
+
+DEFUN ("=", Feqlsign, Seqlsign, 2, 2, 0 /*
+T if two args, both numbers or markers, are equal.
+*/ )
+  (num1, num2)
+     Lisp_Object num1, num2;
+{
+  return arithcompare (num1, num2, equal);
+}
+
+DEFUN ("<", Flss, Slss, 2, 2, 0 /*
+T if first arg is less than second arg.  Both must be numbers or markers.
+*/ )
+  (num1, num2)
+     Lisp_Object num1, num2;
+{
+  return arithcompare (num1, num2, less);
+}
+
+DEFUN (">", Fgtr, Sgtr, 2, 2, 0 /*
+T if first arg is greater than second arg.  Both must be numbers or markers.
+*/ )
+  (num1, num2)
+     Lisp_Object num1, num2;
+{
+  return arithcompare (num1, num2, grtr);
+}
+
+DEFUN ("<=", Fleq, Sleq, 2, 2, 0 /*
+T if first arg is less than or equal to second arg.
+Both must be numbers or markers.
+*/ )
+  (num1, num2)
+     Lisp_Object num1, num2;
+{
+  return arithcompare (num1, num2, less_or_equal);
+}
+
+DEFUN (">=", Fgeq, Sgeq, 2, 2, 0 /*
+T if first arg is greater than or equal to second arg.
+Both must be numbers or markers.
+*/ )
+  (num1, num2)
+     Lisp_Object num1, num2;
+{
+  return arithcompare (num1, num2, grtr_or_equal);
+}
+
+DEFUN ("/=", Fneq, Sneq, 2, 2, 0 /*
+T if first arg is not equal to second arg.  Both must be numbers or markers.
+*/ )
+  (num1, num2)
+     Lisp_Object num1, num2;
+{
+  return arithcompare (num1, num2, notequal);
+}
+
+DEFUN ("zerop", Fzerop, Szerop, 1, 1, 0 /*
+T if NUMBER is zero.
+*/ )
+  (number)
+     Lisp_Object number;
+{
+  CHECK_INT_OR_FLOAT (number);
+
+#ifdef LISP_FLOAT_TYPE
+  if (FLOATP (number))
+    {
+      if (float_data (XFLOAT (number)) == 0.0)
+	return Qt;
+      return Qnil;
+    }
+#endif /* LISP_FLOAT_TYPE */
+
+  if (XINT (number) == 0)
+    return Qt;
+  return Qnil;
+}
+
+/* Convert between a 32-bit value and a cons of two 16-bit values.
+   This is used to pass 32-bit integers to and from the user.
+   Use time_to_lisp() and lisp_to_time() for time values.
+
+   If you're thinking of using this to store a pointer into a Lisp Object
+   for internal purposes (such as when calling record_unwind_protect()),
+   try using make_opaque_ptr()/get_opaque_ptr() instead. */
+Lisp_Object
+word_to_lisp (unsigned int item)
+{
+  return Fcons (make_int (item >> 16), make_int (item & 0xffff));
+}
+
+unsigned int
+lisp_to_word (Lisp_Object item)
+{
+  if (INTP (item))
+    return XINT (item);
+  else
+    {
+      Lisp_Object top = Fcar (item);
+      Lisp_Object bot = Fcdr (item);
+      CHECK_INT (top);
+      CHECK_INT (bot);
+      return (XINT (top) << 16) | (XINT (bot) & 0xffff);
+    }
+}
+
+
+DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0 /*
+Convert NUM to a string by printing it in decimal.
+Uses a minus sign if negative.
+NUM may be an integer or a floating point number.
+*/ )
+  (num)
+     Lisp_Object num;
+{
+  char buffer[VALBITS];
+
+  CHECK_INT_OR_FLOAT (num);
+
+#ifdef LISP_FLOAT_TYPE
+  if (FLOATP (num))
+    {
+      char pigbuf[350];	/* see comments in float_to_string */
+
+      float_to_string (pigbuf, float_data (XFLOAT (num)));
+      return build_string (pigbuf);      
+    }
+#endif /* LISP_FLOAT_TYPE */
+
+  if (sizeof (int) == sizeof (EMACS_INT))
+    sprintf (buffer, "%d", XINT (num));
+  else if (sizeof (long) == sizeof (EMACS_INT))
+    sprintf (buffer, "%ld", (long) XINT (num));
+  else
+    abort ();
+  return build_string (buffer);
+}
+
+DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 1, 0 /*
+Convert STRING to a number by parsing it as a decimal number.
+This parses both integers and floating point numbers.
+It ignores leading spaces and tabs.
+*/ )
+  (string)
+     Lisp_Object string;
+{
+  Lisp_Object value;
+  char *p;
+  CHECK_STRING (string);
+
+  p = (char *) string_data (XSTRING (string));
+  /* Skip any whitespace at the front of the number.  Some versions of
+     atoi do this anyway, so we might as well make Emacs lisp consistent.  */
+  while (*p == ' ' || *p == '\t')
+    p++;
+
+#ifdef LISP_FLOAT_TYPE
+  if (isfloat_string (p))
+    return make_float (atof (p));
+#endif /* LISP_FLOAT_TYPE */
+
+  if (sizeof (int) == sizeof (EMACS_INT))
+    XSETINT (value, atoi (p));
+  else if (sizeof (long) == sizeof (EMACS_INT))
+    XSETINT (value, atol (p));
+  else
+    abort ();
+  return value;
+}
+  
+enum arithop
+  { Aadd, Asub, Amult, Adiv, Alogand, Alogior, Alogxor, Amax, Amin };
+
+#ifdef LISP_FLOAT_TYPE
+static Lisp_Object float_arith_driver (double accum, int argnum, 
+                                       enum arithop code, 
+                                       int nargs, Lisp_Object *args);
+#endif
+
+
+static Lisp_Object
+arith_driver (enum arithop code, int nargs, Lisp_Object *args)
+{
+  Lisp_Object val;
+  REGISTER int argnum;
+  REGISTER EMACS_INT accum = 0;
+  REGISTER EMACS_INT next;
+
+  switch (code)
+    {
+    case Alogior:
+    case Alogxor:
+    case Aadd:
+    case Asub:
+      accum = 0; break;
+    case Amult:
+      accum = 1; break;
+    case Alogand:
+      accum = -1; break;
+    case Adiv:
+    case Amax:
+    case Amin:
+      accum = 0;
+      break;
+    default:
+      abort ();
+    }
+
+  for (argnum = 0; argnum < nargs; argnum++)
+    {
+      val = args[argnum];    /* using args[argnum] as argument to CHECK_INT_OR_FLOAT_... */
+      CHECK_INT_OR_FLOAT_COERCE_CHAR_OR_MARKER (val);
+
+#ifdef LISP_FLOAT_TYPE
+      if (FLOATP (val)) /* time to do serious math */
+	return (float_arith_driver ((double) accum, argnum, code,
+				    nargs, args));
+#endif /* LISP_FLOAT_TYPE */
+      args[argnum] = val;    /* runs into a compiler bug. */
+      next = XINT (args[argnum]);
+      switch (code)
+	{
+	case Aadd: accum += next; break;
+	case Asub:
+	  if (!argnum && nargs != 1)
+	    next = - next;
+	  accum -= next;
+	  break;
+	case Amult: accum *= next; break;
+	case Adiv:
+	  if (!argnum) accum = next;
+	  else
+	    {
+	      if (next == 0)
+		Fsignal (Qarith_error, Qnil);
+	      accum /= next;
+	    }
+	  break;
+	case Alogand: accum &= next; break;
+	case Alogior: accum |= next; break;
+	case Alogxor: accum ^= next; break;
+	case Amax: if (!argnum || next > accum) accum = next; break;
+	case Amin: if (!argnum || next < accum) accum = next; break;
+	}
+    }
+
+  XSETINT (val, accum);
+  return val;
+}
+
+#ifdef LISP_FLOAT_TYPE
+static Lisp_Object
+float_arith_driver (double accum, int argnum, enum arithop code, int nargs,
+		    Lisp_Object *args)
+{
+  REGISTER Lisp_Object val;
+  double next;
+  
+  for (; argnum < nargs; argnum++)
+    {
+      val = args[argnum];    /* using args[argnum] as argument to CHECK_INT_OR_FLOAT_... */
+      CHECK_INT_OR_FLOAT_COERCE_CHAR_OR_MARKER (val);
+
+      if (FLOATP (val))
+	{
+	  next = float_data (XFLOAT (val));
+	}
+      else
+	{
+	  args[argnum] = val;    /* runs into a compiler bug. */
+	  next = XINT (args[argnum]);
+	}
+      switch (code)
+	{
+	case Aadd:
+	  accum += next;
+	  break;
+	case Asub:
+	  if (!argnum && nargs != 1)
+	    next = - next;
+	  accum -= next;
+	  break;
+	case Amult:
+	  accum *= next;
+	  break;
+	case Adiv:
+	  if (!argnum)
+	    accum = next;
+	  else
+	    {
+	      if (next == 0)
+		Fsignal (Qarith_error, Qnil);
+	      accum /= next;
+	    }
+	  break;
+	case Alogand:
+	case Alogior:
+	case Alogxor:
+	  return wrong_type_argument (Qinteger_or_marker_p, val);
+	case Amax:
+	  if (!argnum || isnan (next) || next > accum)
+	    accum = next;
+	  break;
+	case Amin:
+	  if (!argnum || isnan (next) || next < accum)
+	    accum = next;
+	  break;
+	}
+    }
+
+  return make_float (accum);
+}
+#endif /* LISP_FLOAT_TYPE */
+
+DEFUN ("+", Fplus, Splus, 0, MANY, 0 /*
+Return sum of any number of arguments, which are numbers or markers.
+*/ )
+  (nargs, args)
+     int nargs;
+     Lisp_Object *args;
+{
+  return arith_driver (Aadd, nargs, args);
+}
+
+DEFUN ("-", Fminus, Sminus, 0, MANY, 0 /*
+Negate number or subtract numbers or markers.
+With one arg, negates it.  With more than one arg,
+subtracts all but the first from the first.
+*/ )
+  (nargs, args)
+     int nargs;
+     Lisp_Object *args;
+{
+  return arith_driver (Asub, nargs, args);
+}
+
+DEFUN ("*", Ftimes, Stimes, 0, MANY, 0 /*
+Return product of any number of arguments, which are numbers or markers.
+*/ )
+  (nargs, args)
+     int nargs;
+     Lisp_Object *args;
+{
+  return arith_driver (Amult, nargs, args);
+}
+
+DEFUN ("/", Fquo, Squo, 2, MANY, 0 /*
+Return first argument divided by all the remaining arguments.
+The arguments must be numbers or markers.
+*/ )
+  (nargs, args)
+     int nargs;
+     Lisp_Object *args;
+{
+  return arith_driver (Adiv, nargs, args);
+}
+
+DEFUN ("%", Frem, Srem, 2, 2, 0 /*
+Return remainder of first arg divided by second.
+Both must be integers or markers.
+*/ )
+  (num1, num2)
+     Lisp_Object num1, num2;
+{
+  CHECK_INT_COERCE_CHAR_OR_MARKER (num1);
+  CHECK_INT_COERCE_CHAR_OR_MARKER (num2);
+
+  if (ZEROP (num2))
+    Fsignal (Qarith_error, Qnil);
+
+  return (make_int (XINT (num1) % XINT (num2)));
+}
+
+/* Note, ANSI *requires* the presence of the fmod() library routine.
+   If your system doesn't have it, complain to your vendor, because
+   that is a bug. */
+
+#ifndef HAVE_FMOD
+double
+fmod (double f1, double f2)
+{
+  if (f2 < 0.0)
+    f2 = -f2;
+  return (f1 - f2 * floor (f1/f2));
+}
+#endif /* ! HAVE_FMOD */
+
+
+DEFUN ("mod", Fmod, Smod, 2, 2, 0 /*
+Return X modulo Y.
+The result falls between zero (inclusive) and Y (exclusive).
+Both X and Y must be numbers or markers.
+If either argument is a float, a float will be returned.
+*/ )
+  (x, y)
+     Lisp_Object x, y;
+{
+  EMACS_INT i1, i2;
+
+#ifdef LISP_FLOAT_TYPE
+  CHECK_INT_OR_FLOAT_COERCE_CHAR_OR_MARKER (x);
+  CHECK_INT_OR_FLOAT_COERCE_CHAR_OR_MARKER (y);
+
+  if (FLOATP (x) || FLOATP (y))
+    {
+      double f1, f2;
+
+      f1 = ((FLOATP (x)) ? float_data (XFLOAT (x)) : XINT (x));
+      f2 = ((FLOATP (y)) ? float_data (XFLOAT (y)) : XINT (y));
+      if (f2 == 0)
+	Fsignal (Qarith_error, Qnil);
+
+      f1 = fmod (f1, f2); 
+
+      /* If the "remainder" comes out with the wrong sign, fix it.  */
+      if (f2 < 0 ? f1 > 0 : f1 < 0)
+	f1 += f2;
+      return (make_float (f1));
+    }
+#else /* not LISP_FLOAT_TYPE */
+  CHECK_INT_OR_FLOAT_COERCE_CHAR_OR_MARKER (x);
+  CHECK_INT_OR_FLOAT_COERCE_CHAR_OR_MARKER (y);
+#endif /* not LISP_FLOAT_TYPE */
+
+  i1 = XINT (x);
+  i2 = XINT (y);
+
+  if (i2 == 0)
+    Fsignal (Qarith_error, Qnil);
+  
+  i1 %= i2;
+
+  /* If the "remainder" comes out with the wrong sign, fix it.  */
+  if (i2 < 0 ? i1 > 0 : i1 < 0)
+    i1 += i2;
+
+  return (make_int (i1));
+}
+
+
+DEFUN ("max", Fmax, Smax, 1, MANY, 0 /*
+Return largest of all the arguments (which must be numbers or markers).
+The value is always a number; markers are converted to numbers.
+*/ )
+  (nargs, args)
+     int nargs;
+     Lisp_Object *args;
+{
+  return arith_driver (Amax, nargs, args);
+}
+
+DEFUN ("min", Fmin, Smin, 1, MANY, 0 /*
+Return smallest of all the arguments (which must be numbers or markers).
+The value is always a number; markers are converted to numbers.
+*/ )
+  (nargs, args)
+     int nargs;
+     Lisp_Object *args;
+{
+  return arith_driver (Amin, nargs, args);
+}
+
+DEFUN ("logand", Flogand, Slogand, 0, MANY, 0 /*
+Return bitwise-and of all the arguments.
+Arguments may be integers, or markers converted to integers.
+*/ )
+  (nargs, args)
+     int nargs;
+     Lisp_Object *args;
+{
+  return arith_driver (Alogand, nargs, args);
+}
+
+DEFUN ("logior", Flogior, Slogior, 0, MANY, 0 /*
+Return bitwise-or of all the arguments.
+Arguments may be integers, or markers converted to integers.
+*/ )
+  (nargs, args)
+     int nargs;
+     Lisp_Object *args;
+{
+  return arith_driver (Alogior, nargs, args);
+}
+
+DEFUN ("logxor", Flogxor, Slogxor, 0, MANY, 0 /*
+Return bitwise-exclusive-or of all the arguments.
+Arguments may be integers, or markers converted to integers.
+*/ )
+  (nargs, args)
+     int nargs;
+     Lisp_Object *args;
+{
+  return arith_driver (Alogxor, nargs, args);
+}
+
+DEFUN ("ash", Fash, Sash, 2, 2, 0 /*
+Return VALUE with its bits shifted left by COUNT.
+If COUNT is negative, shifting is actually to the right.
+In this case, the sign bit is duplicated.
+*/ )
+  (value, count)
+     Lisp_Object value, count;
+{
+  CHECK_INT_COERCE_CHAR (value);
+  CHECK_INT (count);
+
+  if (XINT (count) > 0)
+    return (make_int (XINT (value) << XINT (count)));
+  else
+    return (make_int (XINT (value) >> -XINT (count)));
+}
+
+DEFUN ("lsh", Flsh, Slsh, 2, 2, 0 /*
+Return VALUE with its bits shifted left by COUNT.
+If COUNT is negative, shifting is actually to the right.
+In this case,  zeros are shifted in on the left.
+*/ )
+  (value, count)
+     Lisp_Object value, count;
+{
+  Lisp_Object val;
+
+  CHECK_INT_COERCE_CHAR (value);
+  CHECK_INT (count);
+
+  if (XINT (count) > 0)
+    XSETINT (val, (EMACS_UINT) XUINT (value) << XINT (count));
+  else
+    XSETINT (val, (EMACS_UINT) XUINT (value) >> -XINT (count));
+  return val;
+}
+
+DEFUN ("1+", Fadd1, Sadd1, 1, 1, 0 /*
+Return NUMBER plus one.  NUMBER may be a number or a marker.
+Markers are converted to integers.
+*/ )
+  (number)
+     Lisp_Object number;
+{
+  CHECK_INT_OR_FLOAT_COERCE_CHAR_OR_MARKER (number);
+
+#ifdef LISP_FLOAT_TYPE
+  if (FLOATP (number))
+    return (make_float (1.0 + float_data (XFLOAT (number))));
+#endif /* LISP_FLOAT_TYPE */
+
+  return (make_int (XINT (number) + 1));
+}
+
+DEFUN ("1-", Fsub1, Ssub1, 1, 1, 0 /*
+Return NUMBER minus one.  NUMBER may be a number or a marker.
+Markers are converted to integers.
+*/ )
+  (number)
+     Lisp_Object number;
+{
+  CHECK_INT_OR_FLOAT_COERCE_CHAR_OR_MARKER (number);
+
+#ifdef LISP_FLOAT_TYPE
+  if (FLOATP (number))
+    return (make_float (-1.0 + (float_data (XFLOAT (number)))));
+#endif /* LISP_FLOAT_TYPE */
+
+  return (make_int (XINT (number) - 1));
+}
+
+DEFUN ("lognot", Flognot, Slognot, 1, 1, 0 /*
+Return the bitwise complement of NUMBER.  NUMBER must be an integer.
+*/ )
+  (number)
+     Lisp_Object number;
+{
+  CHECK_INT (number);
+  return (make_int (~XINT (number)));
+}
+
+
+/************************************************************************/
+/*                              weak lists                              */
+/************************************************************************/
+
+/* A weak list is like a normal list except that elements automatically
+   disappear when no longer in use, i.e. when no longer GC-protected.
+   The basic idea is that we don't mark the elements during GC, but
+   wait for them to be marked elsewhere.  If they're not marked, we
+   remove them.  This is analogous to weak hashtables; see the explanation
+   there for more info. */
+
+static Lisp_Object mark_weak_list (Lisp_Object, void (*) (Lisp_Object));
+static void print_weak_list (Lisp_Object, Lisp_Object, int);
+static int weak_list_equal (Lisp_Object, Lisp_Object, int depth);
+static unsigned long weak_list_hash (Lisp_Object obj, int depth);
+DEFINE_LRECORD_IMPLEMENTATION ("weak-list", weak_list,
+                               mark_weak_list, print_weak_list,
+			       0, weak_list_equal, weak_list_hash,
+			       struct weak_list);
+
+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))
+{
+  return Qnil; /* nichts ist gemarkt */
+}
+
+static void
+print_weak_list (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
+{
+  if (print_readably)
+    error ("printing unreadable object #<weak-list>");
+      
+  write_c_string ("#<weak-list ", printcharfun);
+  print_internal (encode_weak_list_type (XWEAK_LIST (obj)->type),
+		  printcharfun, 0);
+  write_c_string (" ", printcharfun);
+  print_internal (XWEAK_LIST (obj)->list, printcharfun, escapeflag);
+  write_c_string (">", printcharfun);
+}
+
+static int
+weak_list_equal (Lisp_Object o1, Lisp_Object o2, int depth)
+{
+  struct weak_list *w1 = XWEAK_LIST (o1);
+  struct weak_list *w2 = XWEAK_LIST (o2);
+
+  if (w1->type != w2->type ||
+      !internal_equal (w1->list, w2->list, depth + 1))
+    return 0;
+  else
+    return 1;
+}
+
+static unsigned long
+weak_list_hash (Lisp_Object obj, int depth)
+{
+  struct weak_list *w = XWEAK_LIST (obj);
+
+  return HASH2 ((unsigned long) w->type,
+		internal_hash (w->list, depth + 1));
+}
+
+Lisp_Object
+make_weak_list (enum weak_list_type type)
+{
+  Lisp_Object result = Qnil;
+
+  struct weak_list *wl =
+    alloc_lcrecord (sizeof (struct weak_list), lrecord_weak_list);
+  wl->list = Qnil;
+  wl->type = type;
+  XSETWEAK_LIST (result, wl);
+  wl->next_weak = Vall_weak_lists;
+  Vall_weak_lists = result;
+  return result;
+}
+
+/*
+   -- we do not mark the list elements (either the elements themselves
+      or the cons cells that hold them) in the normal marking phase.
+   -- at the end of marking, we go through all weak lists that are
+      marked, and mark the cons cells that hold all marked
+      objects, and possibly parts of the objects themselves.
+      (See alloc.c, "after-mark".)
+   -- after that, we prune away all the cons cells that are not marked.
+
+   WARNING WARNING WARNING WARNING WARNING:
+
+   The code in the following two functions is *unbelievably* tricky.
+   Don't mess with it.  You'll be sorry.
+
+   Linked lists just majorly suck, d'ya know?
+*/
+
+int
+finish_marking_weak_lists (int (*obj_marked_p) (Lisp_Object),
+			   void (*markobj) (Lisp_Object))
+{
+  Lisp_Object rest;
+  int did_mark = 0;
+
+  for (rest = Vall_weak_lists;
+       !GC_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)))
+	/* The weak list is probably garbage.  Ignore it. */
+	continue;
+
+      for (rest2 = XWEAK_LIST (rest)->list;
+	   /* 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);
+	   rest2 = XCDR (rest2))
+	{
+	  Lisp_Object elem;
+	  /* If the element is "marked" (meaning depends on the type
+	     of weak list), we need to mark the cons containing the
+	     element, and maybe the element itself (if only some part
+	     was already marked). */
+	  int need_to_mark_cons = 0;
+	  int need_to_mark_elem = 0;
+
+	  /* If a cons is already marked, then its car is already marked
+	     (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))
+	    break;
+
+	  elem = XCAR (rest2);
+
+	  switch (type)
+	    {
+	    case WEAK_LIST_SIMPLE:
+	      if ((*obj_marked_p) (elem))
+		need_to_mark_cons = 1;
+	      break;
+
+	    case WEAK_LIST_ASSOC:
+	      if (!GC_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)))
+		{
+		  need_to_mark_cons = 1;
+		  /* We still need to mark elem, because it's
+		     probably not marked. */
+		  need_to_mark_elem = 1;
+		}
+	      break;
+
+	    case WEAK_LIST_KEY_ASSOC:
+	      if (!GC_CONSP (elem))
+		{
+		  /* just leave bogus elements there */
+		  need_to_mark_cons = 1;
+		  need_to_mark_elem = 1;
+		}
+	      else if ((*obj_marked_p) (XCAR (elem)))
+		{
+		  need_to_mark_cons = 1;
+		  /* We still need to mark elem and XCDR (elem);
+		     marking elem does both */
+		  need_to_mark_elem = 1;
+		}
+	      break;
+
+	    case WEAK_LIST_VALUE_ASSOC:
+	      if (!GC_CONSP (elem))
+		{
+		  /* just leave bogus elements there */
+		  need_to_mark_cons = 1;
+		  need_to_mark_elem = 1;
+		}
+	      else if ((*obj_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;
+
+	    default:
+	      abort ();
+	    }
+
+	  if (need_to_mark_elem && ! (*obj_marked_p) (elem))
+	    {
+	      (*markobj) (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
+	     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))
+		{
+		  MARK_CONS (ptr);
+		  did_mark = 1;
+		}
+	    }
+	}
+
+      /* 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))
+	{
+	  (markobj) (rest2);
+	  did_mark = 1;
+	}
+    }
+
+  return did_mark;
+}
+
+void
+prune_weak_lists (int (*obj_marked_p) (Lisp_Object))
+{
+  Lisp_Object rest, prev = Qnil;
+
+  for (rest = Vall_weak_lists;
+       !GC_NILP (rest);
+       rest = XWEAK_LIST (rest)->next_weak)
+    {
+      if (! ((*obj_marked_p) (rest)))
+	{
+	  /* This weak list itself is garbage.  Remove it from the list. */
+	  if (GC_NILP (prev))
+	    Vall_weak_lists = XWEAK_LIST (rest)->next_weak;
+	  else
+	    XWEAK_LIST (prev)->next_weak =
+	      XWEAK_LIST (rest)->next_weak;
+	}
+      else
+	{
+	  Lisp_Object rest2, prev2 = Qnil;
+	  Lisp_Object tortoise;
+	  int go_tortoise = 0;
+
+          for (rest2 = XWEAK_LIST (rest)->list, tortoise = rest2;
+	       /* 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);)
+	    {
+	      /* It suffices to check the cons for marking,
+		 regardless of the type of weak list:
+
+		 -- if the cons is pointed to somewhere else,
+		    then it should stay around and will be marked.
+		 -- otherwise, if it should stay around, it will
+		    have been marked in finish_marking_weak_lists().
+		 -- otherwise, it's not marked and should disappear.
+		 */
+	      if (!(*obj_marked_p) (rest2))
+		{
+		  /* bye bye :-( */
+		  if (GC_NILP (prev2))
+		    XWEAK_LIST (rest)->list = XCDR (rest2);
+		  else
+		    XCDR (prev2) = XCDR (rest2);
+		  rest2 = XCDR (rest2);
+		  /* Ouch.  Circularity checking is even trickier
+		     than I thought.  When we cut out a link
+		     like this, we can't advance the turtle or
+		     it'll catch up to us.  Imagine that we're
+		     standing on floor tiles and moving forward --
+		     what we just did here is as if the floor
+		     tile under us just disappeared and all the
+		     ones ahead of us slid one tile towards us.
+		     In other words, we didn't move at all;
+		     if the tortoise was one step behind us
+		     previously, it still is, and therefore
+		     it must not move. */
+		}
+	      else
+		{
+		  prev2 = rest2;
+
+		  /* Implementing circularity checking is trickier here
+		     than in other places because we have to guarantee
+		     that we've processed all elements before exiting
+		     due to a circularity. (In most places, an error
+		     is issued upon encountering a circularity, so it
+		     doesn't really matter if all elements are processed.)
+		     The idea is that we process along with the hare
+		     rather than the tortoise.  If at any point in
+		     our forward process we encounter the tortoise,
+		     we must have already visited the spot, so we exit.
+		     (If we process with the tortoise, we can fail to
+		     process cases where a cons points to itself, or
+		     where cons A points to cons B, which points to
+		     cons A.) */
+		 
+		  rest2 = XCDR (rest2);
+		  if (go_tortoise)
+		    tortoise = XCDR (tortoise);
+		  go_tortoise = !go_tortoise;
+		  if (GC_EQ (rest2, tortoise))
+		    break;
+		}
+	    }
+
+	  prev = rest;
+	}
+    }
+}
+
+static enum weak_list_type
+decode_weak_list_type (Lisp_Object symbol)
+{
+  CHECK_SYMBOL (symbol);
+  if (EQ (symbol, Qsimple))
+    return WEAK_LIST_SIMPLE;
+  if (EQ (symbol, Qassoc))
+    return WEAK_LIST_ASSOC;
+  if (EQ (symbol, Qkey_assoc))
+    return WEAK_LIST_KEY_ASSOC;
+  if (EQ (symbol, Qvalue_assoc))
+    return WEAK_LIST_VALUE_ASSOC;
+
+  signal_simple_error ("Invalid weak list type", symbol);
+  return WEAK_LIST_SIMPLE; /* not reached */
+}
+
+static Lisp_Object
+encode_weak_list_type (enum weak_list_type type)
+{
+  switch (type)
+    {
+    case WEAK_LIST_SIMPLE:
+      return Qsimple;
+    case WEAK_LIST_ASSOC:
+      return Qassoc;
+    case WEAK_LIST_KEY_ASSOC:
+      return Qkey_assoc;
+    case WEAK_LIST_VALUE_ASSOC:
+      return Qvalue_assoc;
+    default:
+      abort ();
+    }
+
+  return Qnil;
+}
+
+DEFUN ("weak-list-p", Fweak_list_p, Sweak_list_p, 1, 1, 0 /*
+Return non-nil if OBJECT is a weak list.
+*/ )
+  (object)
+     Lisp_Object object;
+{
+  return WEAK_LISTP (object) ? Qt : Qnil;
+}
+
+DEFUN ("make-weak-list", Fmake_weak_list, Smake_weak_list, 0, 1, 0 /*
+Create a new weak list.
+A weak list object is an object that contains a list.  This list behaves
+like any other list except that its elements do not count towards
+garbage collection -- if the only pointer to an object in inside a weak
+list (other than pointers in similar objects such as weak hash tables),
+the object is garbage collected and automatically removed from the list.
+This is used internally, for example, to manage the list holding the
+children of an extent -- an extent that is unused but has a parent will
+still be reclaimed, and will automatically be removed from its parent's
+list of children.
+
+Optional argument TYPE specifies the type of the weak list, and defaults
+to `simple'.  Recognized types are
+
+`simple'	Objects in the list disappear if not pointed to.
+`assoc'		Objects in the list disappear if they are conses
+		and either the car or the cdr of the cons is not
+		pointed to.
+`key-assoc'	Objects in the list disappear if they are conses
+		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.
+*/ )
+  (type)
+     Lisp_Object type;
+{
+  if (NILP (type))
+    type = Qsimple;
+
+  return make_weak_list (decode_weak_list_type (type));
+}
+
+DEFUN ("weak-list-type", Fweak_list_type, Sweak_list_type, 1, 1, 0 /*
+Return the type of the given weak-list object.
+*/ )
+  (weak)
+     Lisp_Object weak;
+{
+  CHECK_WEAK_LIST (weak);
+  return encode_weak_list_type (XWEAK_LIST (weak)->type);
+}
+
+DEFUN ("weak-list-list", Fweak_list_list, Sweak_list_list, 1, 1, 0 /*
+Return the list contained in a weak-list object.
+*/ )
+  (weak)
+     Lisp_Object weak;
+{
+  CHECK_WEAK_LIST (weak);
+  return XWEAK_LIST_LIST (weak);
+}
+
+DEFUN ("set-weak-list-list", Fset_weak_list_list, Sset_weak_list_list,
+       2, 2, 0 /*
+Change the list contained in a weak-list object.
+*/ )
+  (weak, new_list)
+     Lisp_Object weak, new_list;
+{
+  CHECK_WEAK_LIST (weak);
+  XWEAK_LIST_LIST (weak) = new_list;
+  return new_list;
+}
+
+
+/************************************************************************/
+/*                            initialization                            */
+/************************************************************************/
+
+static SIGTYPE
+arith_error (int signo)
+{
+  EMACS_REESTABLISH_SIGNAL (signo, arith_error);
+  EMACS_UNBLOCK_SIGNAL (signo);
+  signal_error (Qarith_error, Qnil);
+}
+
+void
+init_data_very_early (void)
+{
+  /* Don't do this if just dumping out.
+     We don't want to call `signal' in this case
+     so that we don't have trouble with dumping
+     signal-delivering routines in an inconsistent state.  */
+#ifndef CANNOT_DUMP
+  if (!initialized)
+    return;
+#endif /* CANNOT_DUMP */
+  signal (SIGFPE, arith_error);
+#ifdef uts
+  signal (SIGEMT, arith_error);
+#endif /* uts */
+}
+
+void
+init_errors_once_early (void)
+{
+  defsymbol (&Qerror_conditions, "error-conditions");
+  defsymbol (&Qerror_message, "error-message");
+
+  /* We declare the errors here because some other deferrors depend
+     on some of the errors below. */
+
+  /* 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 (&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 (&Qmalformed_list, "malformed-list",
+	    "Malformed list", Qerror);
+  deferror (&Qmalformed_property_list, "malformed-property-list",
+	    "Malformed property list", Qerror);
+  deferror (&Qcircular_list, "circular-list",
+	    "Circular list", Qerror);
+  deferror (&Qcircular_property_list, "circular-property-list",
+	    "Circular property list", Qerror);
+  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 (&Qio_error, "io-error", "IO Error", Qerror);
+  deferror (&Qend_of_file, "end-of-file", "End of stream", Qio_error);
+
+  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);
+}
+
+void
+syms_of_data (void)
+{
+  defsymbol (&Qcons, "cons");
+  defsymbol (&Qkeyword, "keyword");
+  /* Qstring, Qinteger, Qsymbol, Qvector defined in general.c */
+
+  defsymbol (&Qquote, "quote");
+  defsymbol (&Qlambda, "lambda");
+  defsymbol (&Qsignal, "signal");
+  defsymbol (&Qtop_level, "top-level");
+  defsymbol (&Qignore, "ignore");
+
+  defsymbol (&Qlistp, "listp");
+  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 (&Qcompiled_functionp, "compiled-function-p");
+  defsymbol (&Qchar_or_string_p, "char-or-string-p");
+  defsymbol (&Qmarkerp, "markerp");
+  defsymbol (&Qinteger_or_marker_p, "integer-or-marker-p");
+  /* HACK for 19.x only. */
+  defsymbol (&Qinteger_char_or_marker_p, "integer-or-marker-p");
+
+#ifdef LISP_FLOAT_TYPE
+  defsymbol (&Qfloatp, "floatp");
+#endif /* LISP_FLOAT_TYPE */
+  defsymbol (&Qnumberp, "numberp");
+  defsymbol (&Qnumber_or_marker_p, "number-or-marker-p");
+  /* HACK for 19.x only. */
+  defsymbol (&Qnumber_char_or_marker_p, "number-or-marker-p");
+
+  defsymbol (&Qcdr, "cdr");
+
+  defsymbol (&Qweak_listp, "weak-list-p");
+
+  defsubr (&Swrong_type_argument);
+
+  defsubr (&Seq);
+  defsubr (&Snull);
+  defsubr (&Slistp);
+  defsubr (&Snlistp);
+  defsubr (&Sconsp);
+  defsubr (&Satom);
+  defsubr (&Schar_or_string_p);
+  defsubr (&Scharacterp);
+  defsubr (&Sintegerp);
+  defsubr (&Sinteger_or_marker_p);
+  defsubr (&Snumberp);
+  defsubr (&Snumber_or_marker_p);
+#ifdef LISP_FLOAT_TYPE
+  defsubr (&Sfloatp);
+#endif /* LISP_FLOAT_TYPE */
+  defsubr (&Snatnump);
+  defsubr (&Ssymbolp);
+  defsubr (&Skeywordp);
+  defsubr (&Sstringp);
+  defsubr (&Svectorp);
+  defsubr (&Sbitp);
+  defsubr (&Sbit_vector_p);
+  defsubr (&Sarrayp);
+  defsubr (&Ssequencep);
+  defsubr (&Smarkerp);
+  defsubr (&Ssubrp);
+  defsubr (&Ssubr_min_args);
+  defsubr (&Ssubr_max_args);
+  defsubr (&Scompiled_function_p);
+  defsubr (&Stype_of);
+  defsubr (&Scar);
+  defsubr (&Scdr);
+  defsubr (&Scar_safe);
+  defsubr (&Scdr_safe);
+  defsubr (&Ssetcar);
+  defsubr (&Ssetcdr);
+  defsubr (&Sindirect_function);
+  defsubr (&Saref);
+  defsubr (&Saset);
+
+  defsubr (&Scompiled_function_instructions);
+  defsubr (&Scompiled_function_constants);
+  defsubr (&Scompiled_function_stack_depth);
+  defsubr (&Scompiled_function_arglist);
+  defsubr (&Scompiled_function_interactive);
+  defsubr (&Scompiled_function_doc_string);
+  defsubr (&Scompiled_function_domain);
+#ifdef COMPILED_FUNCTION_ANNOTATION_HACK
+  defsubr (&Scompiled_function_annotation);
+#endif
+
+  defsubr (&Snumber_to_string);
+  defsubr (&Sstring_to_number);
+  defsubr (&Seqlsign);
+  defsubr (&Slss);
+  defsubr (&Sgtr);
+  defsubr (&Sleq);
+  defsubr (&Sgeq);
+  defsubr (&Sneq);
+  defsubr (&Szerop);
+  defsubr (&Splus);
+  defsubr (&Sminus);
+  defsubr (&Stimes);
+  defsubr (&Squo);
+  defsubr (&Srem);
+  defsubr (&Smod);
+  defsubr (&Smax);
+  defsubr (&Smin);
+  defsubr (&Slogand);
+  defsubr (&Slogior);
+  defsubr (&Slogxor);
+  defsubr (&Slsh);
+  defsubr (&Sash);
+  defsubr (&Sadd1);
+  defsubr (&Ssub1);
+  defsubr (&Slognot);
+
+  defsubr (&Sweak_list_p);
+  defsubr (&Smake_weak_list);
+  defsubr (&Sweak_list_type);
+  defsubr (&Sweak_list_list);
+  defsubr (&Sset_weak_list_list);
+}
+
+void
+vars_of_data (void)
+{
+  /* This must not be staticpro'd */
+  Vall_weak_lists = Qnil;
+}