diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.in | 2 | ||||
-rw-r--r-- | src/buffer.c | 4 | ||||
-rw-r--r-- | src/eval.c | 2 | ||||
-rw-r--r-- | src/fns.c | 53 | ||||
-rw-r--r-- | src/marker.c | 7 |
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) |