summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in2
-rw-r--r--src/buffer.c4
-rw-r--r--src/eval.c2
-rw-r--r--src/fns.c53
-rw-r--r--src/marker.c7
5 files changed, 59 insertions, 9 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index 9e105c157b9..8478dc14a85 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -431,7 +431,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
thread.o systhread.o \
$(if $(HYBRID_MALLOC),sheap.o) \
$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
- $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) $(JSON_OBJ) $(GMP_OBJ)
+ $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) $(JSON_OBJ)
obj = $(base_obj) $(NS_OBJC_OBJ)
## Object files used on some machine or other.
diff --git a/src/buffer.c b/src/buffer.c
index 5bd9b37702f..03c10cc7ae5 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1942,8 +1942,8 @@ cleaning up all windows currently displaying the buffer to be killed. */)
}
/* Since we've unlinked the markers, the overlays can't be here any more
either. */
- b->overlays_before = NULL;
- b->overlays_after = NULL;
+ set_buffer_overlays_before (b, NULL);
+ set_buffer_overlays_after (b, NULL);
/* Reset the local variables, so that this buffer's local values
won't be protected from GC. They would be protected
diff --git a/src/eval.c b/src/eval.c
index 10e53cf9aed..cf5ca3b4bbd 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -221,7 +221,7 @@ init_eval_once (void)
/* Don't forget to update docs (lispref node "Local Variables"). */
if (!NATIVE_COMP_FLAG)
{
- max_specpdl_size = 1600; /* 1500 is not enough for cl-generic.el. */
+ max_specpdl_size = 1800; /* See bug#46818. */
max_lisp_eval_depth = 800;
}
else
diff --git a/src/fns.c b/src/fns.c
index 7914bd47790..b193ad648a9 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -54,10 +54,55 @@ DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
return argument;
}
+static Lisp_Object
+ccall2 (Lisp_Object (f) (ptrdiff_t nargs, Lisp_Object *args),
+ Lisp_Object arg1, Lisp_Object arg2)
+{
+ Lisp_Object args[2] = {arg1, arg2};
+ return f (2, args);
+}
+
+static Lisp_Object
+get_random_bignum (Lisp_Object limit)
+{
+ /* This is a naive transcription into bignums of the fixnum algorithm.
+ I'd be quite surprised if that's anywhere near the best algorithm
+ for it. */
+ while (true)
+ {
+ Lisp_Object val = make_fixnum (0);
+ Lisp_Object lim = limit;
+ int bits = 0;
+ int bitsperiteration = FIXNUM_BITS - 1;
+ do
+ {
+ /* Shift by one so it is a valid positive fixnum. */
+ EMACS_INT rand = get_random () >> 1;
+ Lisp_Object lrand = make_fixnum (rand);
+ bits += bitsperiteration;
+ val = ccall2 (Flogior,
+ Fash (val, make_fixnum (bitsperiteration)),
+ lrand);
+ lim = Fash (lim, make_fixnum (- bitsperiteration));
+ }
+ while (!EQ (lim, make_fixnum (0)));
+ /* Return the remainder, except reject the rare case where
+ get_random returns a number so close to INTMASK that the
+ remainder isn't random. */
+ Lisp_Object remainder = Frem (val, limit);
+ if (!NILP (ccall2 (Fleq,
+ ccall2 (Fminus, val, remainder),
+ ccall2 (Fminus,
+ Fash (make_fixnum (1), make_fixnum (bits)),
+ limit))))
+ return remainder;
+ }
+}
+
DEFUN ("random", Frandom, Srandom, 0, 1, 0,
doc: /* Return a pseudo-random integer.
By default, return a fixnum; all fixnums are equally likely.
-With positive fixnum LIMIT, return random integer in interval [0,LIMIT).
+With positive integer LIMIT, return random integer in interval [0,LIMIT).
With argument t, set the random number seed from the system's entropy
pool if available, otherwise from less-random volatile data such as the time.
With a string argument, set the seed based on the string's contents.
@@ -71,6 +116,12 @@ See Info node `(elisp)Random Numbers' for more details. */)
init_random ();
else if (STRINGP (limit))
seed_random (SSDATA (limit), SBYTES (limit));
+ if (BIGNUMP (limit))
+ {
+ if (0 > mpz_sgn (*xbignum_val (limit)))
+ xsignal2 (Qwrong_type_argument, Qnatnump, limit);
+ return get_random_bignum (limit);
+ }
val = get_random ();
if (FIXNUMP (limit) && 0 < XFIXNUM (limit))
diff --git a/src/marker.c b/src/marker.c
index 59791513170..2b137b14c8f 100644
--- a/src/marker.c
+++ b/src/marker.c
@@ -634,16 +634,15 @@ set_marker_restricted_both (Lisp_Object marker, Lisp_Object buffer,
/* Detach a marker so that it no longer points anywhere and no longer
slows down editing. Do not free the marker, though, as a change
function could have inserted it into an undo list (Bug#30931). */
+
void
detach_marker (Lisp_Object marker)
{
Fset_marker (marker, Qnil, Qnil);
}
-/* Remove MARKER from the chain of whatever buffer it is in,
- leaving it points to nowhere. This is called during garbage
- collection, so we must be careful to ignore and preserve
- mark bits, including those in chain fields of markers. */
+/* Remove MARKER from the chain of whatever buffer it is in. Set its
+ buffer NULL. */
void
unchain_marker (register struct Lisp_Marker *marker)