commit a1fa3d24d7f96542530f30c28daf9bf8aaaeae13 (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Mon Mar 14 06:48:34 2022 +0000 Clean up some Haiku toolkit code * src/haiku_io.c (haiku_read_with_timeout): Accept `bigtime_t' instead of `time_t' for values which are cast to bigtime_t anyway. * src/haiku_support.cc (BMenu_run): Read all help events instead of just one. * src/haiku_support.h: Update prototypes. diff --git a/src/haiku_io.c b/src/haiku_io.c index ff684df433..f9fa4095f9 100644 --- a/src/haiku_io.c +++ b/src/haiku_io.c @@ -145,7 +145,7 @@ haiku_read (enum haiku_event_type *type, void *buf, ssize_t len) Input is blocked when an attempt to read is in progress. */ int haiku_read_with_timeout (enum haiku_event_type *type, void *buf, ssize_t len, - time_t timeout, bool popup_menu_p) + bigtime_t timeout, bool popup_menu_p) { int32 typ; port_id from = (popup_menu_p diff --git a/src/haiku_support.cc b/src/haiku_support.cc index cb8ffaf2d7..27d4bbafaf 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -2957,7 +2957,7 @@ BMenu_run (void *menu, int x, int y, if (infos[0].events & B_EVENT_READ) { - if (!haiku_read_with_timeout (&type, buf, 200, 1000000, true)) + while (!haiku_read_with_timeout (&type, buf, 200, 0, true)) { switch (type) { diff --git a/src/haiku_support.h b/src/haiku_support.h index 8b21fafad7..41bd1e1c84 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -420,7 +420,7 @@ extern "C" extern int haiku_read_with_timeout (enum haiku_event_type *type, void *buf, ssize_t len, - time_t timeout, bool popup_menu_p); + bigtime_t timeout, bool popup_menu_p); extern int haiku_write (enum haiku_event_type type, void *buf); commit 1a07854e0e8825da1d1acfc1701eb30787546ee5 Merge: be38fed34e 8e7a3f21e0 Author: Stefan Kangas Date: Mon Mar 14 06:30:42 2022 +0100 ; Merge from origin/emacs-28 The following commit was skipped: 8e7a3f21e0 Fix evaluation of negated argument predicates in Eshell commit be38fed34e7f30a2ee7619bca8c93c065e488a5f Merge: faab1b2002 1ec4063017 Author: Stefan Kangas Date: Mon Mar 14 06:30:41 2022 +0100 Merge from origin/emacs-28 1ec4063017 ; * admin/make-tarball.txt: Minor updates. commit faab1b20028d11b9f35beacba4b2b278ac0cdab3 Author: Po Lu Date: Mon Mar 14 02:45:55 2022 +0000 Fix extraneous overscroll activation on Haiku * src/haiku_support.cc (class EmacsScrollBar): New field `maybe_overscroll'. (MouseDown): Set that field. (MouseUp): Clear that field. (MouseMoved): Also test `maybe_overscroll' to ensure that a grab started inside the scroll bar. diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 1c1be178d2..cb8ffaf2d7 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -1571,6 +1571,7 @@ class EmacsScrollBar : public BScrollBar bool handle_button = false; bool in_overscroll = false; bool can_overscroll = false; + bool maybe_overscroll = false; BPoint last_overscroll; int last_reported_overscroll_value; int max_value, real_max_value; @@ -1784,6 +1785,7 @@ class EmacsScrollBar : public BScrollBar if (buttons == B_PRIMARY_MOUSE_BUTTON) { + maybe_overscroll = true; r = ButtonRegionFor (HAIKU_SCROLL_BAR_UP_BUTTON); if (r.Contains (pt)) @@ -1833,6 +1835,7 @@ class EmacsScrollBar : public BScrollBar BView *parent; in_overscroll = false; + maybe_overscroll = false; if (handle_button) { @@ -1922,7 +1925,9 @@ class EmacsScrollBar : public BScrollBar return; } } - else if (can_overscroll && (buttons == B_PRIMARY_MOUSE_BUTTON)) + else if (can_overscroll + && (buttons == B_PRIMARY_MOUSE_BUTTON) + && maybe_overscroll) { value = Value (); commit a63bac7adef9b17521e804a67a574764d6e8b2b6 Author: Po Lu Date: Mon Mar 14 09:05:48 2022 +0800 Fix tool-bar highlight persisting after mouse moves onto WM frame * src/xterm.c (handle_one_xevent): Always report MotionNotify coordinates in terms of the edit widget. diff --git a/src/xterm.c b/src/xterm.c index 397b5bfc7a..06cb933209 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -11210,6 +11210,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, case MotionNotify: { + XMotionEvent xmotion = event->xmotion; + previous_help_echo_string = help_echo_string; help_echo_string = Qnil; @@ -11250,8 +11252,18 @@ handle_one_xevent (struct x_display_info *dpyinfo, || !NILP (focus_follows_mouse))) { static Lisp_Object last_mouse_window; + + if (xmotion.window != FRAME_X_WINDOW (f)) + { + XTranslateCoordinates (FRAME_X_DISPLAY (f), + xmotion.window, FRAME_X_WINDOW (f), + xmotion.x, xmotion.y, &xmotion.x, + &xmotion.y, &xmotion.subwindow); + xmotion.window = FRAME_X_WINDOW (f); + } + Lisp_Object window = window_from_coordinates - (f, event->xmotion.x, event->xmotion.y, 0, false, false); + (f, xmotion.x, xmotion.y, 0, false, false); /* A window will be autoselected only when it is not selected now and the last mouse movement event was @@ -12367,6 +12379,14 @@ handle_one_xevent (struct x_display_info *dpyinfo, #endif if (f) { + if (xev->event != FRAME_X_WINDOW (f)) + { + XTranslateCoordinates (FRAME_X_DISPLAY (f), + xev->event, FRAME_X_WINDOW (f), + ev.x, ev.y, &ev.x, &ev.y, &dummy); + ev.window = FRAME_X_WINDOW (f); + } + /* Maybe generate a SELECT_WINDOW_EVENT for `mouse-autoselect-window' but don't let popup menus interfere with this (Bug#1261). */ commit 485a8fcbf4974466022798c0159e954af9482cf1 Author: Glenn Morris Date: Sun Mar 13 18:03:11 2022 -0700 * src/bytecode.c: Include sysstdio.h, for fprint, stderr. ; Ref https://hydra.nixos.org/build/169207408 diff --git a/src/bytecode.c b/src/bytecode.c index b26146c27f..8704e6069d 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -21,6 +21,7 @@ along with GNU Emacs. If not, see . */ #include "lisp.h" #include "blockinput.h" +#include "sysstdio.h" #include "character.h" #include "buffer.h" #include "keyboard.h" commit 17fd48efab9c8c42147c1d6319ca653781eac1e6 Author: Po Lu Date: Mon Mar 14 00:54:10 2022 +0000 Enable overscroll on Haiku horizontal scroll bars * src/haiku_support.cc (MouseMoved): Handle horizontal directions correctly. * src/haikuterm.c (haiku_set_horizontal_scroll_bar_thumb): Enable overscrolling on scroll bar widget. diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 3941dc0409..1c1be178d2 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -1882,7 +1882,10 @@ class EmacsScrollBar : public BScrollBar if (in_overscroll) { - diff = point.y - last_overscroll.y; + if (horizontal) + diff = point.x - last_overscroll.x; + else + diff = point.y - last_overscroll.y; if (diff < 0) { @@ -1894,10 +1897,16 @@ class EmacsScrollBar : public BScrollBar bounds = Bounds (); bounds.InsetBy (1.0, 1.0); value = overscroll_start_value; - trough_size = BE_RECT_HEIGHT (bounds); - trough_size -= BE_RECT_WIDTH (bounds) / 2; + trough_size = (horizontal + ? BE_RECT_WIDTH (bounds) + : BE_RECT_HEIGHT (bounds)); + trough_size -= (horizontal + ? BE_RECT_HEIGHT (bounds) + : BE_RECT_WIDTH (bounds)) / 2; if (info.double_arrows) - trough_size -= BE_RECT_WIDTH (bounds) / 2; + trough_size -= (horizontal + ? BE_RECT_HEIGHT (bounds) + : BE_RECT_WIDTH (bounds)) / 2; value += ((double) range / trough_size) * diff; diff --git a/src/haikuterm.c b/src/haikuterm.c index 7982869589..52846fc145 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -503,7 +503,7 @@ haiku_set_horizontal_scroll_bar_thumb (struct scroll_bar *bar, int portion, bar->page_size = size; BView_scroll_bar_update (scroll_bar, lrint (size), BE_SB_MAX, - ceil (value), bar->dragging, false); + ceil (value), bar->dragging ? -1 : 0, true); } static struct scroll_bar * commit 57172d0a35d999c7f7bab6615cb42fe92b172bba Author: Po Lu Date: Mon Mar 14 00:45:00 2022 +0000 Fix scroll bar movement right before overscroll begins on Haiku * src/haikuterm.c (haiku_set_scroll_bar_thumb): Make sure value and size are within bounds even if portion adjustment is off. diff --git a/src/haikuterm.c b/src/haikuterm.c index 6f8d2eaac5..7982869589 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -455,35 +455,30 @@ haiku_set_scroll_bar_thumb (struct scroll_bar *bar, int portion, /* When the thumb is at the bottom, position == whole. So we need to increase `whole' to make space for the thumb. */ whole += portion; - - if (whole <= 0) - top = 0, shown = 1; - else - { - top = (double) position / whole; - shown = (double) portion / whole; - } - - /* Slider size. Must be in the range [1 .. MAX - MIN] where MAX - is the scroll bar's maximum and MIN is the scroll bar's minimum - value. */ - size = clip_to_bounds (1, shown * BE_SB_MAX, BE_SB_MAX); - - /* Position. Must be in the range [MIN .. MAX - SLIDER_SIZE]. */ - value = top * BE_SB_MAX; - value = min (value, BE_SB_MAX - size); - - if (!bar->dragging) - bar->page_size = size; } else - { - bar->page_size = 0; + bar->page_size = 0; - size = (((double) portion / whole) * BE_SB_MAX); - value = (((double) position / whole) * BE_SB_MAX); + if (whole <= 0) + top = 0, shown = 1; + else + { + top = (double) position / whole; + shown = (double) portion / whole; } + /* Slider size. Must be in the range [1 .. MAX - MIN] where MAX + is the scroll bar's maximum and MIN is the scroll bar's minimum + value. */ + size = clip_to_bounds (1, shown * BE_SB_MAX, BE_SB_MAX); + + /* Position. Must be in the range [MIN .. MAX - SLIDER_SIZE]. */ + value = top * BE_SB_MAX; + value = min (value, BE_SB_MAX - size); + + if (!bar->dragging && scroll_bar_adjust_thumb_portion_p) + bar->page_size = size; + BView_scroll_bar_update (scroll_bar, lrint (size), BE_SB_MAX, ceil (value), (scroll_bar_adjust_thumb_portion_p commit 510f1f2e72a467cdaae25c4354e5ce3579ca1ca9 Author: Lars Ingebrigtsen Date: Sun Mar 13 21:15:35 2022 +0100 Really fix find-func for defgeneric * lisp/emacs-lisp/find-func.el (find-function-regexp): Really add defgeneric. diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el index 208d68d1ab..96eaf1ab64 100644 --- a/lisp/emacs-lisp/find-func.el +++ b/lisp/emacs-lisp/find-func.el @@ -61,7 +61,7 @@ "^\\s-*(\\(def\\(ine-skeleton\\|ine-generic-mode\\|ine-derived-mode\\|\ ine\\(?:-global\\)?-minor-mode\\|ine-compilation-mode\\|un-cvs-mode\\|\ foo\\|\\(?:[^icfgv]\\|g[^r]\\)\\(\\w\\|\\s_\\)+\\*?\\)\\|easy-mmode-define-[a-z-]+\\|easy-menu-define\\|\ -cl-\\(?:defun\\|defmethod\\|generic\\)\\|\ +cl-\\(?:defun\\|defmethod\\|defgeneric\\)\\|\ menu-bar-make-toggle\\|menu-bar-make-toggle-command\\)" find-function-space-re "\\('\\|(quote \\)?%s\\(\\s-\\|$\\|[()]\\)") commit 525c01c43a75b6190243530a70cd4943abe980a7 Author: Lars Ingebrigtsen Date: Sun Mar 13 21:13:49 2022 +0100 Make vtable sorting stable * lisp/emacs-lisp/vtable.el (vtable--sort): Make the sorting stable. diff --git a/lisp/emacs-lisp/vtable.el b/lisp/emacs-lisp/vtable.el index d8577c1976..8d77733531 100644 --- a/lisp/emacs-lisp/vtable.el +++ b/lisp/emacs-lisp/vtable.el @@ -456,22 +456,26 @@ This also updates the displayed table." (pcase-dolist (`(,index . ,direction) (vtable-sort-by table)) (let ((cache (vtable--cache table)) (numerical (vtable-column--numerical - (elt (vtable-columns table) index)))) + (elt (vtable-columns table) index))) + (numcomp (if (eq direction 'descend) + #'> #'<)) + (stringcomp (if (eq direction 'descend) + #'string> #'string<))) (setcar cache (sort (car cache) (lambda (e1 e2) (let ((c1 (elt e1 (1+ index))) (c2 (elt e2 (1+ index)))) (if numerical - (< (car c1) (car c2)) - (string< (if (stringp (car c1)) - (car c1) - (format "%s" (car c1))) - (if (stringp (car c2)) - (car c2) - (format "%s" (car c2))))))))) - (when (eq direction 'descend) - (setcar cache (nreverse (car cache))))))) + (funcall numcomp (car c1) (car c2)) + (funcall + stringcomp + (if (stringp (car c1)) + (car c1) + (format "%s" (car c1))) + (if (stringp (car c2)) + (car c2) + (format "%s" (car c2)))))))))))) (defun vtable--indicator (table index) (let ((order (car (last (vtable-sort-by table))))) commit dd91aac508b5727e10d370f2405dbcecf9578417 Author: Paul Eggert Date: Sun Mar 13 12:03:46 2022 -0700 Clang debug notes * etc/DEBUG: Don’t imply Clang works as well as GCC when debugging Emacs. Mention a coverage problem with Clang. diff --git a/etc/DEBUG b/etc/DEBUG index dd33b42f19..7d2f810d07 100644 --- a/etc/DEBUG +++ b/etc/DEBUG @@ -947,10 +947,10 @@ several kinds of low-level problems in C code, including: * Passing invalid values to some builtin functions, e.g., __builtin_clz (0). * Reaching __builtin_unreachable calls (in Emacs, 'eassume' failure). -To use UndefinedBehaviorSanitizer with GCC and similar compilers, -append '-fsanitize=undefined' to CFLAGS, either when running -'configure' or running 'make'. When supported, you can also specify -'bound-strict' and 'float-cast-overflow'. For example: +To use GCC's UndefinedBehaviorSanitizer, append '-fsanitize=undefined' +to CFLAGS, either when running 'configure' or running 'make'. +When supported, you can also specify 'bound-strict' and +'float-cast-overflow'. For example: ./configure \ CFLAGS='-O0 -g3 -fsanitize=undefined,bounds-strict,float-cast-overflow' @@ -958,6 +958,11 @@ append '-fsanitize=undefined' to CFLAGS, either when running You may need to append '-static-libubsan' to CFLAGS if your version of GCC is installed in an unusual location. +Clang's UB sanitizer can also be used, but has coverage problems. +You'll need '-fsanitize=undefined -fno-sanitize=pointer-overflow' to +suppress misguided warnings about adding zero to a null pointer, +although this also suppresses any valid pointer overflow warnings. + When using GDB to debug an executable with undefined-behavior sanitization, the GDB command: commit 8e7a3f21e00649bacc01be627edd45ff01b51a33 (refs/remotes/origin/emacs-28) Author: Jim Porter Date: Sun Mar 13 15:36:37 2022 +0100 Fix evaluation of negated argument predicates in Eshell * lisp/eshell/em-pred.el (eshell-add-pred-func): Let-bind 'pred' so the lambdas see the original value (bug#54369). Committed on the wrong branch. Do not merge to master. diff --git a/lisp/eshell/em-pred.el b/lisp/eshell/em-pred.el index b1dc7abc69..4f4e85c1a6 100644 --- a/lisp/eshell/em-pred.el +++ b/lisp/eshell/em-pred.el @@ -364,12 +364,12 @@ resultant list of strings." (defun eshell-add-pred-func (pred funcs negate follow) "Add the predicate function PRED to FUNCS." - (if negate - (setq pred (lambda (file) - (not (funcall pred file))))) - (if follow - (setq pred (lambda (file) - (funcall pred (file-truename file))))) + (when negate + (setq pred (let ((pred pred)) + (lambda (file) (not (funcall pred file)))))) + (when follow + (setq pred (let ((pred pred)) + (lambda (file) (funcall pred (file-truename file)))))) (cons pred funcs)) (defun eshell-pred-user-or-group (mod-char mod-type attr-index get-id-func) commit ea3c147d2dcb65840ad5ec5c4d8786d36a5ea0dc Author: Jim Porter Date: Sun Mar 13 15:36:37 2022 +0100 Fix evaluation of negated argument predicates in Eshell * lisp/eshell/em-pred.el (eshell-add-pred-func): Let-bind 'pred' so the lambdas see the original value (bug#54369). diff --git a/lisp/eshell/em-pred.el b/lisp/eshell/em-pred.el index 216c71f59e..970329e12a 100644 --- a/lisp/eshell/em-pred.el +++ b/lisp/eshell/em-pred.el @@ -360,12 +360,12 @@ resultant list of strings." (defun eshell-add-pred-func (pred funcs negate follow) "Add the predicate function PRED to FUNCS." - (if negate - (setq pred (lambda (file) - (not (funcall pred file))))) - (if follow - (setq pred (lambda (file) - (funcall pred (file-truename file))))) + (when negate + (setq pred (let ((pred pred)) + (lambda (file) (not (funcall pred file)))))) + (when follow + (setq pred (let ((pred pred)) + (lambda (file) (funcall pred (file-truename file)))))) (cons pred funcs)) (defun eshell-pred-user-or-group (mod-char mod-type attr-index get-id-func) commit edb8481ce15404d9157e104958aef22b05b606a7 Author: Mattias Engdegård Date: Sun Mar 13 19:35:50 2022 +0100 * src/bytecode.c (sf_set_ptr): Cast pointer to type of right size. diff --git a/src/bytecode.c b/src/bytecode.c index 9356ebeb6c..b26146c27f 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -393,7 +393,7 @@ sf_get_ptr (Lisp_Object *fp, enum stack_frame_index index) INLINE void sf_set_ptr (Lisp_Object *fp, enum stack_frame_index index, void *value) { - fp[index] = XIL ((EMACS_INT)value); + fp[index] = XIL ((uintptr_t)value); } INLINE Lisp_Object * commit 3ed79cdbf21039fa209c421f746c0b49ec33f4da Author: Mattias Engdegård Date: Sun Mar 13 17:26:05 2022 +0100 Separate bytecode stack Use a dedicated stack for bytecode, instead of using the C stack. Stack frames are managed explicitly and we stay in the same exec_byte_code activation throughout bytecode function calls and returns. In other words, exec_byte_code no longer uses recursion for calling bytecode functions. This results in better performance, and bytecode recursion is no longer limited by the size of the C stack. The bytecode stack is currently of fixed size but overflow is handled gracefully by signalling a Lisp error instead of the hard crash that we get now. In addition, GC marking of the stack is now faster and more precise. Full precision could be attained if desired. * src/alloc.c (ATTRIBUTE_NO_SANITIZE_ADDRESS): Make non-static. * src/bytecode.c (enum stack_frame_index, BC_STACK_SIZE) (sf_get_ptr, sf_set_ptr, sf_get_lisp_ptr, sf_set_lisp_ptr) (sf_get_saved_pc, sf_set_saved_pc, init_bc_thread, free_bc_thread) (mark_bytecode, Finternal_stack_stats, valid_sp): New. (exec_byte_code): Adapt to use the new bytecode stack. (syms_of_bytecode): Add defsubr. * src/eval.c (unwind_to_catch): Restore saved stack frame. (push_handler_nosignal): Save stack frame. * src/lisp.h (struct handler): Add act_rec member. (get_act_rec, set_act_rec): New. * src/thread.c (mark_one_thread): Call mark_bytecode. (finalize_one_thread): Free bytecode thread state. (Fmake_thread, init_threads): Set up bytecode thread state. * src/thread.h (struct bc_thread_state): New. (struct thread_state): Add bytecode thread state. diff --git a/src/alloc.c b/src/alloc.c index 9ed94dc8a1..c19e3dabb6 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -4928,7 +4928,7 @@ mark_maybe_pointer (void *p, bool symbol_only) /* Mark Lisp objects referenced from the address range START..END or END..START. */ -static void ATTRIBUTE_NO_SANITIZE_ADDRESS +void ATTRIBUTE_NO_SANITIZE_ADDRESS mark_memory (void const *start, void const *end) { char const *pp; diff --git a/src/bytecode.c b/src/bytecode.c index 7c390c0d40..9356ebeb6c 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -334,6 +334,166 @@ bcall0 (Lisp_Object f) Ffuncall (1, &f); } +/* Layout of the stack frame header. */ +enum stack_frame_index { + SFI_SAVED_FP, /* previous frame pointer */ + + /* In a frame called directly from C, the following two members are NULL. */ + SFI_SAVED_TOP, /* previous stack pointer */ + SFI_SAVED_PC, /* previous program counter */ + + SFI_FUN, /* current function object */ + + SF_SIZE /* number of words in the header */ +}; + +/* The bytecode stack size in Lisp words. + This is a fairly generous amount, but: + - if users need more, we could allocate more, or just reserve the address + space and allocate on demand + - if threads are used more, then it might be a good idea to reduce the + per-thread overhead in time and space + - for maximum flexibility but a small runtime penalty, we could allocate + the stack in smaller chunks as needed +*/ +#define BC_STACK_SIZE (512 * 1024) + +/* Bytecode interpreter stack: + + |--------------| -- + |fun | | ^ stack growth + |saved_pc | | | direction + |saved_top ------- | + fp--->|saved_fp ---- | | current frame + |--------------| | | | (called from bytecode in this example) + | (free) | | | | + top-->| ...stack... | | | | + : ... : | | | + |incoming args | | | | + |--------------| | | -- + |fun | | | | + |saved_pc | | | | + |saved_top | | | | + |saved_fp |<- | | previous frame + |--------------| | | + | (free) | | | + | ...stack... |<---- | + : ... : | + |incoming args | | + |--------------| -- + : : +*/ + +INLINE void * +sf_get_ptr (Lisp_Object *fp, enum stack_frame_index index) +{ + return XLP (fp[index]); +} + +INLINE void +sf_set_ptr (Lisp_Object *fp, enum stack_frame_index index, void *value) +{ + fp[index] = XIL ((EMACS_INT)value); +} + +INLINE Lisp_Object * +sf_get_lisp_ptr (Lisp_Object *fp, enum stack_frame_index index) +{ + return sf_get_ptr (fp, index); +} + +INLINE void +sf_set_lisp_ptr (Lisp_Object *fp, enum stack_frame_index index, + Lisp_Object *value) +{ + sf_set_ptr (fp, index, value); +} + +INLINE const unsigned char * +sf_get_saved_pc (Lisp_Object *fp) +{ + return sf_get_ptr (fp, SFI_SAVED_PC); +} + +INLINE void +sf_set_saved_pc (Lisp_Object *fp, const unsigned char *value) +{ + sf_set_ptr (fp, SFI_SAVED_PC, (unsigned char *)value); +} + +void +init_bc_thread (struct bc_thread_state *bc) +{ + bc->stack = xmalloc (BC_STACK_SIZE * sizeof *bc->stack); + bc->stack_end = bc->stack + BC_STACK_SIZE; + /* Put a dummy header at the bottom to indicate the first free location. */ + bc->fp = bc->stack; + memset (bc->fp, 0, SF_SIZE * sizeof *bc->stack); +} + +void +free_bc_thread (struct bc_thread_state *bc) +{ + xfree (bc->stack); +} + +void +mark_bytecode (struct bc_thread_state *bc) +{ + Lisp_Object *fp = bc->fp; + Lisp_Object *top = NULL; /* stack pointer of topmost frame not known */ + for (;;) + { + Lisp_Object *next_fp = sf_get_lisp_ptr (fp, SFI_SAVED_FP); + /* Only the dummy frame at the bottom has saved_fp = NULL. */ + if (!next_fp) + break; + mark_object (fp[SFI_FUN]); + Lisp_Object *frame_base = next_fp + SF_SIZE; + if (top) + { + /* The stack pointer of a frame is known: mark the part of the stack + above it conservatively. This includes any outgoing arguments. */ + mark_memory (top + 1, fp); + /* Mark the rest of the stack precisely. */ + mark_objects (frame_base, top + 1 - frame_base); + } + else + { + /* The stack pointer is unknown -- mark everything conservatively. */ + mark_memory (frame_base, fp); + } + top = sf_get_lisp_ptr (fp, SFI_SAVED_TOP); + fp = next_fp; + } +} + +DEFUN ("internal-stack-stats", Finternal_stack_stats, Sinternal_stack_stats, + 0, 0, 0, + doc: /* internal */) + (void) +{ + struct bc_thread_state *bc = ¤t_thread->bc; + int nframes = 0; + int nruns = 0; + for (Lisp_Object *fp = bc->fp; fp; fp = sf_get_lisp_ptr (fp, SFI_SAVED_FP)) + { + nframes++; + if (sf_get_lisp_ptr (fp, SFI_SAVED_TOP) == NULL) + nruns++; + } + fprintf (stderr, "%d stack frames, %d runs\n", nframes, nruns); + return Qnil; +} + +/* Whether a stack pointer is valid in the current frame. */ +INLINE bool +valid_sp (struct bc_thread_state *bc, Lisp_Object *sp) +{ + Lisp_Object *fp = bc->fp; + return sp < fp && sp + 1 >= sf_get_lisp_ptr (fp, SFI_SAVED_FP) + SF_SIZE; +} + /* Execute the byte-code in FUN. ARGS_TEMPLATE is the function arity encoded as an integer (the one in FUN is ignored), and ARGS, of size NARGS, should be a vector of the actual arguments. The @@ -347,37 +507,49 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, #ifdef BYTE_CODE_METER int volatile this_op = 0; #endif + unsigned char quitcounter = 1; + struct bc_thread_state *bc = ¤t_thread->bc; + + /* Values used for the first stack record when called from C. */ + Lisp_Object *top = NULL; + unsigned char const *pc = NULL; Lisp_Object bytestr = AREF (fun, COMPILED_BYTECODE); + setup_frame: ; eassert (!STRING_MULTIBYTE (bytestr)); eassert (string_immovable_p (bytestr)); + /* FIXME: in debug mode (!NDEBUG, BYTE_CODE_SAFE or enabled checking), + save the specpdl index on function entry and check that it is the same + when returning, to detect unwind imbalances. This would require adding + a field to the frame header. */ + Lisp_Object vector = AREF (fun, COMPILED_CONSTANTS); Lisp_Object maxdepth = AREF (fun, COMPILED_STACK_DEPTH); ptrdiff_t const_length = ASIZE (vector); ptrdiff_t bytestr_length = SCHARS (bytestr); Lisp_Object *vectorp = XVECTOR (vector)->contents; - unsigned char quitcounter = 1; - /* Allocate two more slots than required, because... */ - EMACS_INT stack_items = XFIXNAT (maxdepth) + 2; - USE_SAFE_ALLOCA; - void *alloc; - SAFE_ALLOCA_LISP (alloc, stack_items); - Lisp_Object *stack_base = alloc; - /* ... we plonk BYTESTR and VECTOR there to ensure that they survive - GC (bug#33014), since these variables aren't used directly beyond - the interpreter prologue and wouldn't be found in the stack frame - otherwise. */ - stack_base[0] = bytestr; - stack_base[1] = vector; - Lisp_Object *top = stack_base + 1; - Lisp_Object *stack_lim = top + stack_items; + EMACS_INT max_stack = XFIXNAT (maxdepth); + Lisp_Object *frame_base = bc->fp + SF_SIZE; + Lisp_Object *fp = frame_base + max_stack; + + if (fp + SF_SIZE > bc->stack_end) + error ("Bytecode stack overflow"); + + /* Save the function object so that the bytecode and vector are + held from removal by the GC. */ + fp[SFI_FUN] = fun; + /* Save previous stack pointer and pc in the new frame. If we came + directly from outside, these will be NULL. */ + sf_set_lisp_ptr (fp, SFI_SAVED_TOP, top); + sf_set_saved_pc (fp, pc); + sf_set_lisp_ptr (fp, SFI_SAVED_FP, bc->fp); + bc->fp = fp; + + top = frame_base - 1; unsigned char const *bytestr_data = SDATA (bytestr); - unsigned char const *pc = bytestr_data; -#if BYTE_CODE_SAFE || !defined NDEBUG - specpdl_ref count = SPECPDL_INDEX (); -#endif + pc = bytestr_data; /* ARGS_TEMPLATE is composed of bit fields: bits 0..6 minimum number of arguments @@ -404,7 +576,7 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, int op; enum handlertype type; - if (BYTE_CODE_SAFE && ! (stack_base <= top && top < stack_lim)) + if (BYTE_CODE_SAFE && !valid_sp (bc, top)) emacs_abort (); #ifdef BYTE_CODE_METER @@ -636,36 +808,45 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, error ("Lisp nesting exceeds `max-lisp-eval-depth'"); } - ptrdiff_t numargs = op; - Lisp_Object fun = TOP; - Lisp_Object *args = &TOP + 1; + ptrdiff_t call_nargs = op; + Lisp_Object call_fun = TOP; + Lisp_Object *call_args = &TOP + 1; - specpdl_ref count1 = record_in_backtrace (fun, args, numargs); + specpdl_ref count1 = record_in_backtrace (call_fun, + call_args, call_nargs); maybe_gc (); if (debug_on_next_call) do_debug_on_call (Qlambda, count1); - Lisp_Object original_fun = fun; - if (SYMBOLP (fun)) - fun = XSYMBOL (fun)->u.s.function; + Lisp_Object original_fun = call_fun; + if (SYMBOLP (call_fun)) + call_fun = XSYMBOL (call_fun)->u.s.function; Lisp_Object template; Lisp_Object bytecode; - Lisp_Object val; - if (COMPILEDP (fun) + if (COMPILEDP (call_fun) // Lexical binding only. - && (template = AREF (fun, COMPILED_ARGLIST), + && (template = AREF (call_fun, COMPILED_ARGLIST), FIXNUMP (template)) // No autoloads. - && (bytecode = AREF (fun, COMPILED_BYTECODE), + && (bytecode = AREF (call_fun, COMPILED_BYTECODE), !CONSP (bytecode))) - val = exec_byte_code (fun, XFIXNUM (template), numargs, args); - else if (SUBRP (fun) && !SUBR_NATIVE_COMPILED_DYNP (fun)) - val = funcall_subr (XSUBR (fun), numargs, args); + { + fun = call_fun; + bytestr = bytecode; + args_template = XFIXNUM (template); + nargs = call_nargs; + args = call_args; + goto setup_frame; + } + + Lisp_Object val; + if (SUBRP (call_fun) && !SUBR_NATIVE_COMPILED_DYNP (call_fun)) + val = funcall_subr (XSUBR (call_fun), call_nargs, call_args); else - val = funcall_general (original_fun, numargs, args); + val = funcall_general (original_fun, call_nargs, call_args); lisp_eval_depth--; - if (backtrace_debug_on_exit (specpdl_ref_to_ptr (count1))) + if (backtrace_debug_on_exit (specpdl_ptr - 1)) val = call_debugger (list2 (Qexit, val)); specpdl_ptr--; @@ -731,7 +912,40 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, NEXT; CASE (Breturn): - goto exit; + { + Lisp_Object *saved_top = sf_get_lisp_ptr (bc->fp, SFI_SAVED_TOP); + if (saved_top) + { + Lisp_Object val = TOP; + + lisp_eval_depth--; + if (backtrace_debug_on_exit (specpdl_ptr - 1)) + val = call_debugger (list2 (Qexit, val)); + specpdl_ptr--; + + top = saved_top; + pc = sf_get_saved_pc (bc->fp); + Lisp_Object *fp = sf_get_lisp_ptr (bc->fp, SFI_SAVED_FP); + bc->fp = fp; + + Lisp_Object fun = fp[SFI_FUN]; + Lisp_Object bytestr = AREF (fun, COMPILED_BYTECODE); + Lisp_Object vector = AREF (fun, COMPILED_CONSTANTS); + bytestr_data = SDATA (bytestr); + vectorp = XVECTOR (vector)->contents; + if (BYTE_CODE_SAFE) + { + /* Only required for checking, not for execution. */ + const_length = ASIZE (vector); + bytestr_length = SCHARS (bytestr); + } + + TOP = val; + NEXT; + } + else + goto exit; + } CASE (Bdiscard): DISCARD (1); @@ -786,9 +1000,23 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, if (sys_setjmp (c->jmp)) { struct handler *c = handlerlist; + handlerlist = c->next; top = c->bytecode_top; op = c->bytecode_dest; - handlerlist = c->next; + Lisp_Object *fp = bc->fp; + + Lisp_Object fun = fp[SFI_FUN]; + Lisp_Object bytestr = AREF (fun, COMPILED_BYTECODE); + Lisp_Object vector = AREF (fun, COMPILED_CONSTANTS); + bytestr_data = SDATA (bytestr); + vectorp = XVECTOR (vector)->contents; + if (BYTE_CODE_SAFE) + { + /* Only required for checking, not for execution. */ + const_length = ASIZE (vector); + bytestr_length = SCHARS (bytestr); + } + pc = bytestr_data; PUSH (c->val); goto op_branch; } @@ -1527,20 +1755,9 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, exit: -#if BYTE_CODE_SAFE || !defined NDEBUG - if (!specpdl_ref_eq (SPECPDL_INDEX (), count)) - { - /* Binds and unbinds are supposed to be compiled balanced. */ - if (specpdl_ref_lt (count, SPECPDL_INDEX ())) - unbind_to (count, Qnil); - error ("binding stack not balanced (serious byte compiler bug)"); - } -#endif - /* The byte code should have been properly pinned. */ - eassert (SDATA (bytestr) == bytestr_data); + bc->fp = sf_get_lisp_ptr (bc->fp, SFI_SAVED_FP); Lisp_Object result = TOP; - SAFE_FREE (); return result; } @@ -1562,6 +1779,7 @@ void syms_of_bytecode (void) { defsubr (&Sbyte_code); + defsubr (&Sinternal_stack_stats); #ifdef BYTE_CODE_METER diff --git a/src/eval.c b/src/eval.c index b1c1a8c676..c46b74ac40 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1233,6 +1233,7 @@ unwind_to_catch (struct handler *catch, enum nonlocal_exit type, eassert (handlerlist == catch); lisp_eval_depth = catch->f_lisp_eval_depth; + set_act_rec (current_thread, catch->act_rec); sys_longjmp (catch->jmp, 1); } @@ -1673,6 +1674,7 @@ push_handler_nosignal (Lisp_Object tag_ch_val, enum handlertype handlertype) c->next = handlerlist; c->f_lisp_eval_depth = lisp_eval_depth; c->pdlcount = SPECPDL_INDEX (); + c->act_rec = get_act_rec (current_thread); c->poll_suppress_count = poll_suppress_count; c->interrupt_input_blocked = interrupt_input_blocked; handlerlist = c; diff --git a/src/lisp.h b/src/lisp.h index 5e3590675d..8053bbc977 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3546,6 +3546,7 @@ struct handler sys_jmp_buf jmp; EMACS_INT f_lisp_eval_depth; specpdl_ref pdlcount; + Lisp_Object *act_rec; int poll_suppress_count; int interrupt_input_blocked; }; @@ -4087,6 +4088,7 @@ extern void alloc_unexec_pre (void); extern void alloc_unexec_post (void); extern void mark_stack (char const *, char const *); extern void flush_stack_call_func1 (void (*func) (void *arg), void *arg); +extern void mark_memory (void const *start, void const *end); /* Force callee-saved registers and register windows onto the stack, so that conservative garbage collection can see their values. */ @@ -4855,6 +4857,21 @@ extern void syms_of_bytecode (void); extern Lisp_Object exec_byte_code (Lisp_Object, ptrdiff_t, ptrdiff_t, Lisp_Object *); extern Lisp_Object get_byte_code_arity (Lisp_Object); +extern void init_bc_thread (struct bc_thread_state *bc); +extern void free_bc_thread (struct bc_thread_state *bc); +extern void mark_bytecode (struct bc_thread_state *bc); + +INLINE Lisp_Object * +get_act_rec (struct thread_state *th) +{ + return th->bc.fp; +} + +INLINE void +set_act_rec (struct thread_state *th, Lisp_Object *act_rec) +{ + th->bc.fp = act_rec; +} /* Defined in macros.c. */ extern void init_macros (void); diff --git a/src/thread.c b/src/thread.c index b5b7d7c0d7..c6742341fb 100644 --- a/src/thread.c +++ b/src/thread.c @@ -671,6 +671,8 @@ mark_one_thread (struct thread_state *thread) mark_object (tem); } + mark_bytecode (&thread->bc); + /* No need to mark Lisp_Object members like m_last_thing_searched, as mark_threads_callback does that by calling mark_object. */ } @@ -839,6 +841,7 @@ finalize_one_thread (struct thread_state *state) free_search_regs (&state->m_search_regs); free_search_regs (&state->m_saved_search_regs); sys_cond_destroy (&state->thread_condvar); + free_bc_thread (&state->bc); } DEFUN ("make-thread", Fmake_thread, Smake_thread, 1, 2, 0, @@ -868,6 +871,8 @@ If NAME is given, it must be a string; it names the new thread. */) new_thread->m_specpdl_end = new_thread->m_specpdl + size; new_thread->m_specpdl_ptr = new_thread->m_specpdl; + init_bc_thread (&new_thread->bc); + sys_cond_init (&new_thread->thread_condvar); /* We'll need locking here eventually. */ @@ -1127,6 +1132,7 @@ init_threads (void) sys_mutex_lock (&global_lock); current_thread = &main_thread.s; main_thread.s.thread_id = sys_thread_self (); + init_bc_thread (&main_thread.s.bc); } void diff --git a/src/thread.h b/src/thread.h index f2755045b2..a29af702d1 100644 --- a/src/thread.h +++ b/src/thread.h @@ -33,6 +33,13 @@ along with GNU Emacs. If not, see . */ #include "sysselect.h" /* FIXME */ #include "systhread.h" +/* Byte-code interpreter thread state. */ +struct bc_thread_state { + Lisp_Object *fp; /* current frame pointer (see bytecode.c) */ + Lisp_Object *stack; + Lisp_Object *stack_end; +}; + struct thread_state { union vectorlike_header header; @@ -181,6 +188,8 @@ struct thread_state /* Threads are kept on a linked list. */ struct thread_state *next_thread; + + struct bc_thread_state bc; } GCALIGNED_STRUCT; INLINE bool commit 267f41c7ce1e02f392b57aa338d387e7627df184 Author: Mattias Engdegård Date: Tue Jan 18 13:10:05 2022 +0100 Simplify exec_byte_code arguments Pass the function object and encoded arity, not the other components. This speeds up several call paths and is necessary for improvements to come. * src/bytecode.c (Fbyte_code): Make a new byte code object for execution. This is slower but performance isn't critical here. (exec_byte_code): Retrieve components from the passed function. * src/eval.c (fetch_and_exec_byte_code): * src/lisp.h (exec_byte_code): Update signature. diff --git a/src/bytecode.c b/src/bytecode.c index 286a8d675d..7c390c0d40 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -324,9 +324,8 @@ If the third argument is incorrect, Emacs may crash. */) the original unibyte form. */ bytestr = Fstring_as_unibyte (bytestr); } - pin_string (bytestr); // Bytecode must be immovable. - - return exec_byte_code (bytestr, vector, maxdepth, 0, 0, NULL); + Lisp_Object args[] = {0, bytestr, vector, maxdepth}; + return exec_byte_code (Fmake_byte_code (4, args), 0, 0, NULL); } static void @@ -335,24 +334,26 @@ bcall0 (Lisp_Object f) Ffuncall (1, &f); } -/* Execute the byte-code in BYTESTR. VECTOR is the constant vector, and - MAXDEPTH is the maximum stack depth used (if MAXDEPTH is incorrect, - emacs may crash!). ARGS_TEMPLATE is the function arity encoded as an - integer, and ARGS, of size NARGS, should be a vector of the actual - arguments. The arguments in ARGS are pushed on the stack according - to ARGS_TEMPLATE before executing BYTESTR. */ +/* Execute the byte-code in FUN. ARGS_TEMPLATE is the function arity + encoded as an integer (the one in FUN is ignored), and ARGS, of + size NARGS, should be a vector of the actual arguments. The + arguments in ARGS are pushed on the stack according to + ARGS_TEMPLATE before executing FUN. */ Lisp_Object -exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, - ptrdiff_t args_template, ptrdiff_t nargs, Lisp_Object *args) +exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, + ptrdiff_t nargs, Lisp_Object *args) { #ifdef BYTE_CODE_METER int volatile this_op = 0; #endif + Lisp_Object bytestr = AREF (fun, COMPILED_BYTECODE); + eassert (!STRING_MULTIBYTE (bytestr)); eassert (string_immovable_p (bytestr)); - + Lisp_Object vector = AREF (fun, COMPILED_CONSTANTS); + Lisp_Object maxdepth = AREF (fun, COMPILED_STACK_DEPTH); ptrdiff_t const_length = ASIZE (vector); ptrdiff_t bytestr_length = SCHARS (bytestr); Lisp_Object *vectorp = XVECTOR (vector)->contents; @@ -657,10 +658,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, // No autoloads. && (bytecode = AREF (fun, COMPILED_BYTECODE), !CONSP (bytecode))) - val = exec_byte_code (bytecode, - AREF (fun, COMPILED_CONSTANTS), - AREF (fun, COMPILED_STACK_DEPTH), - XFIXNUM (template), numargs, args); + val = exec_byte_code (fun, XFIXNUM (template), numargs, args); else if (SUBRP (fun) && !SUBR_NATIVE_COMPILED_DYNP (fun)) val = funcall_subr (XSUBR (fun), numargs, args); else diff --git a/src/eval.c b/src/eval.c index b747d2cbb6..b1c1a8c676 100644 --- a/src/eval.c +++ b/src/eval.c @@ -3105,10 +3105,7 @@ fetch_and_exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, if (CONSP (AREF (fun, COMPILED_BYTECODE))) Ffetch_bytecode (fun); - return exec_byte_code (AREF (fun, COMPILED_BYTECODE), - AREF (fun, COMPILED_CONSTANTS), - AREF (fun, COMPILED_STACK_DEPTH), - args_template, nargs, args); + return exec_byte_code (fun, args_template, nargs, args); } static Lisp_Object diff --git a/src/lisp.h b/src/lisp.h index 0b649a92f5..5e3590675d 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4852,8 +4852,8 @@ extern int read_bytecode_char (bool); /* Defined in bytecode.c. */ extern void syms_of_bytecode (void); -extern Lisp_Object exec_byte_code (Lisp_Object, Lisp_Object, Lisp_Object, - ptrdiff_t, ptrdiff_t, Lisp_Object *); +extern Lisp_Object exec_byte_code (Lisp_Object, ptrdiff_t, + ptrdiff_t, Lisp_Object *); extern Lisp_Object get_byte_code_arity (Lisp_Object); /* Defined in macros.c. */ commit 35f75b63b51660190b48020c048701ae8553ea1f Author: Michael Albinus Date: Sun Mar 13 16:50:14 2022 +0100 * lisp/net/ange-ftp.el (ange-ftp-ls): Make a loop when sanitizing LSARGS. diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el index ef8527fada..9937c022d9 100644 --- a/lisp/net/ange-ftp.el +++ b/lisp/net/ange-ftp.el @@ -2554,7 +2554,7 @@ can parse the output from a DIR listing for a host of type TYPE.") FILE is the full name of the remote file, LSARGS is any args to pass to the `ls' command, and PARSE specifies that the output should be parsed and stored away in the internal cache." - (when (string-match "--" lsargs) + (while (string-match "--" lsargs) (require 'ls-lisp) (setq lsargs (ls-lisp--sanitize-switches lsargs))) ;; If parse is t, we assume that file is a directory. i.e. we only parse commit 466a7e44d729683277dab41dba7395b36802a8cf Author: Lars Ingebrigtsen Date: Sun Mar 13 15:07:59 2022 +0100 Add cl-defgeneric to find-func, too * lisp/emacs-lisp/find-func.el (find-function-regexp): Add cl-defgeneric, too (bug#54343). diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el index 777334a7a7..208d68d1ab 100644 --- a/lisp/emacs-lisp/find-func.el +++ b/lisp/emacs-lisp/find-func.el @@ -61,7 +61,7 @@ "^\\s-*(\\(def\\(ine-skeleton\\|ine-generic-mode\\|ine-derived-mode\\|\ ine\\(?:-global\\)?-minor-mode\\|ine-compilation-mode\\|un-cvs-mode\\|\ foo\\|\\(?:[^icfgv]\\|g[^r]\\)\\(\\w\\|\\s_\\)+\\*?\\)\\|easy-mmode-define-[a-z-]+\\|easy-menu-define\\|\ -cl-\\(?:defun\\|defmethod\\)\\|\ +cl-\\(?:defun\\|defmethod\\|generic\\)\\|\ menu-bar-make-toggle\\|menu-bar-make-toggle-command\\)" find-function-space-re "\\('\\|(quote \\)?%s\\(\\s-\\|$\\|[()]\\)") commit 49f70b603fbc6f3c6cb923a066998b1687b566be Author: Po Lu Date: Sun Mar 13 12:56:55 2022 +0000 Allow overscrolling on Haiku scroll bars that are full * src/haiku_support.cc (MouseMoved): Allow overscrolling even if portion is less than 1.0. diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 9c9aa7f35b..3941dc0409 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -1921,7 +1921,7 @@ class EmacsScrollBar : public BScrollBar { BScrollBar::MouseMoved (point, transit, msg); - if (value == Value () && Proportion () < 1.0f) + if (value == Value ()) { overscroll_start_value = value; in_overscroll = true; commit 6ab04b59b14d56468fcb28a142278fb1b1666b86 Author: Po Lu Date: Sun Mar 13 12:53:01 2022 +0000 Fix pointer event tracking on top of Haiku scroll bars * src/haiku_support.cc (MouseDown): Set correct mouse event mask in case the scroll bar widget decides to not do that. diff --git a/src/haiku_support.cc b/src/haiku_support.cc index a14600cb33..9c9aa7f35b 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -1817,6 +1817,9 @@ class EmacsScrollBar : public BScrollBar rq.window = Window (); rq.scroll_bar = this; + SetMouseEventMask (B_POINTER_EVENTS, (B_SUSPEND_VIEW_FOCUS + | B_LOCK_WINDOW_FOCUS)); + haiku_write (SCROLL_BAR_DRAG_EVENT, &rq); out: commit 1b8711f42640983167b0b63c4b0cb39b66e373c4 Author: Po Lu Date: Sun Mar 13 12:32:15 2022 +0000 Fix splurious button events being generated on Haiku * src/haiku_support.cc (MouseDown, MouseUp): Don't process if the grab is not appropriate for the buttons that were pressed. diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 5fc8d2675e..a14600cb33 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -1469,17 +1469,19 @@ class EmacsView : public BView this->GetMouse (&point, &buttons, false); rq.window = this->Window (); - rq.btn_no = 0; - if (!(previous_buttons & B_PRIMARY_MOUSE_BUTTON) && - (buttons & B_PRIMARY_MOUSE_BUTTON)) + if (!(previous_buttons & B_PRIMARY_MOUSE_BUTTON) + && (buttons & B_PRIMARY_MOUSE_BUTTON)) rq.btn_no = 0; - else if (!(previous_buttons & B_SECONDARY_MOUSE_BUTTON) && - (buttons & B_SECONDARY_MOUSE_BUTTON)) + else if (!(previous_buttons & B_SECONDARY_MOUSE_BUTTON) + && (buttons & B_SECONDARY_MOUSE_BUTTON)) rq.btn_no = 2; - else if (!(previous_buttons & B_TERTIARY_MOUSE_BUTTON) && - (buttons & B_TERTIARY_MOUSE_BUTTON)) + else if (!(previous_buttons & B_TERTIARY_MOUSE_BUTTON) + && (buttons & B_TERTIARY_MOUSE_BUTTON)) rq.btn_no = 1; + else + return; + previous_buttons = buttons; rq.x = point.x; @@ -1515,7 +1517,6 @@ class EmacsView : public BView this->GetMouse (&point, &buttons, false); rq.window = this->Window (); - rq.btn_no = 0; if ((previous_buttons & B_PRIMARY_MOUSE_BUTTON) && !(buttons & B_PRIMARY_MOUSE_BUTTON)) @@ -1526,6 +1527,9 @@ class EmacsView : public BView else if ((previous_buttons & B_TERTIARY_MOUSE_BUTTON) && !(buttons & B_TERTIARY_MOUSE_BUTTON)) rq.btn_no = 1; + else + return; + previous_buttons = buttons; rq.x = point.x; commit 676dffff4b063cf4f7667bd0ca6ded3a03704d2c Author: Po Lu Date: Sun Mar 13 18:58:42 2022 +0800 Fix setting IM spot after key press events * src/xterm.c (handle_one_xevent): Check f is not NULL before trying to set its status area and set preedit spot location after KeyPress events. diff --git a/src/xterm.c b/src/xterm.c index 18a8d5b431..397b5bfc7a 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -11038,6 +11038,15 @@ handle_one_xevent (struct x_display_info *dpyinfo, } done_keysym: #ifdef HAVE_X_I18N + if (f) + { + struct window *w = XWINDOW (f->selected_window); + xic_set_preeditarea (w, w->cursor.x, w->cursor.y); + + if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea)) + xic_set_statusarea (f); + } + /* Don't dispatch this event since XtDispatchEvent calls XFilterEvent, and two calls in a row may freeze the client. */ @@ -11507,11 +11516,11 @@ handle_one_xevent (struct x_display_info *dpyinfo, #ifdef HAVE_X_I18N - if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea)) - xic_set_statusarea (f); - if (f) { + if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea)) + xic_set_statusarea (f); + struct window *w = XWINDOW (f->selected_window); xic_set_preeditarea (w, w->cursor.x, w->cursor.y); } @@ -13598,8 +13607,14 @@ handle_one_xevent (struct x_display_info *dpyinfo, xi_done_keysym: #ifdef HAVE_X_I18N - if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea)) - xic_set_statusarea (f); + if (f) + { + struct window *w = XWINDOW (f->selected_window); + xic_set_preeditarea (w, w->cursor.x, w->cursor.y); + + if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea)) + xic_set_statusarea (f); + } #endif if (must_free_data) XFreeEventData (dpyinfo->display, &event->xcookie); commit c6287816f2af5a954d735fa62ce714db2067a3db Author: Mattias Engdegård Date: Sun Mar 13 11:01:59 2022 +0100 Fix esh-proc-tests on macOS * test/lisp/eshell/esh-proc-tests.el (esh-proc-test/kill-pipeline): Add pattern matching output when killing a process on macOS (and possibly other BSDs). diff --git a/test/lisp/eshell/esh-proc-tests.el b/test/lisp/eshell/esh-proc-tests.el index d2184688f3..7f461d1813 100644 --- a/test/lisp/eshell/esh-proc-tests.el +++ b/test/lisp/eshell/esh-proc-tests.el @@ -62,7 +62,7 @@ prompt. See bug#54136." (eshell-wait-for-subprocess t) (should (string-match-p ;; "interrupt\n" is for MS-Windows. - (rx (or "interrupt\n" "killed\n")) + (rx (or "interrupt\n" "killed\n" "killed: 9\n")) (buffer-substring-no-properties output-start (eshell-end-of-output))))))) commit 15b303dfc94ed6ad59685cb57f7474524bd2c0c5 Author: Eli Zaretskii Date: Sun Mar 13 11:40:55 2022 +0200 ; * etc/NEWS: Fix typo. diff --git a/etc/NEWS b/etc/NEWS index be53675f08..b1aac3d6d0 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1670,7 +1670,8 @@ Use 'indian-tml-base-digits-table' if you want digits translation. -- ** 'indian-tml-itrans-v5-hash' no longer translates digits. -Use 'indian-tml-itrans-digits-v5-hash' if you digits translation. +Use 'indian-tml-itrans-digits-v5-hash' if you want digits +translation. * Changes in Emacs 29.1 on Non-Free Operating Systems commit 04ad6b2263876d78b6a567ff548859ce15204c8d Author: Eli Zaretskii Date: Sun Mar 13 10:20:37 2022 +0200 ; * etc/NEWS: Cleanups as followup to bug#50143. diff --git a/etc/NEWS b/etc/NEWS index 273fa77640..be53675f08 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -159,11 +159,12 @@ An autoload definition appears just as a '(defun . NAME)' and the '(t . NAME)' entries are not generated any more. --- -** The Tamil input methods do not insert Tamil digits anymore. +** The Tamil input methods no longer insert Tamil digits. The input methods 'tamil-itrans' and 'tamil-inscript' no longer insert -the Tamil digit. To get back the previous behaviour, use the -'tamil-itrans-digits' and 'tamil-inscript-digits' input methods -instead. +the Tamil digits, as those digit characters are not used nowadays by +speakers of the Tamil language. To get back the previous behavior, +use the new 'tamil-itrans-digits' and 'tamil-inscript-digits' input +methods instead. * Changes in Emacs 29.1 @@ -1670,6 +1671,7 @@ Use 'indian-tml-base-digits-table' if you want digits translation. -- ** 'indian-tml-itrans-v5-hash' no longer translates digits. Use 'indian-tml-itrans-digits-v5-hash' if you digits translation. + * Changes in Emacs 29.1 on Non-Free Operating Systems commit 9a786aea735a19dec636a8ad5fb30dff419951ca Author: Visuwesh Date: Sun Mar 13 12:31:16 2022 +0530 * quail.el (quail-define-package): Describe VAR form in DOCSTRING better. Bug#50143 Copyright-paperwork-exempt: yes diff --git a/lisp/international/quail.el b/lisp/international/quail.el index 14d4c383b2..529cf97215 100644 --- a/lisp/international/quail.el +++ b/lisp/international/quail.el @@ -412,8 +412,8 @@ If it is nil, the current key is shown. DOCSTRING is the documentation string of this package. The command `describe-input-method' shows this string while replacing the form -\\=\\ in the string by the value of VAR. That value should be a -string. For instance, the form \\=\\ is +\\=\\=\\=\\ in the string by the value of VAR. That value should be a +string. For instance, the form \\=\\=\\=\\ is replaced by a description about how to select a translation from a list of candidates. commit b447fd1a3e8085352eaced1f14145bd22764e552 Author: Visuwesh Date: Sun Mar 13 11:16:38 2022 +0530 Follow contemporary practices in the Tamil input methods * lisp/language/ind-util.el (indian-tml-base-digits-table): New table to translate digits. (indian-tml-base-table): Don't translate digits. (indian-tml-itrans-digits-v5-hash): Hashtable that translates digits. * lisp/leim/quail/indian.el (quail-tamil-itrans-compute-signs-table) (quail-tamil-itrans-various-signs-table) (quail-tamil-itrans-various-signs-and-digits-table): Separate out the digits from the signs table using the function 'quail-tamil-itrans-compute-signs-table'. (tamil-itrans-digits, tamil-inscript-digits): New input methods that translates digits. (tamil-itrans, tamil-inscript): Fix table inclusion. * etc/NEWS: Announce the change. Fixes bug#50143. Copyright-paperwork-exempt: yes diff --git a/etc/NEWS b/etc/NEWS index faac1fbc91..273fa77640 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -158,6 +158,13 @@ beginning. An autoload definition appears just as a '(defun . NAME)' and the '(t . NAME)' entries are not generated any more. +--- +** The Tamil input methods do not insert Tamil digits anymore. +The input methods 'tamil-itrans' and 'tamil-inscript' no longer insert +the Tamil digit. To get back the previous behaviour, use the +'tamil-itrans-digits' and 'tamil-inscript-digits' input methods +instead. + * Changes in Emacs 29.1 @@ -1656,6 +1663,13 @@ when used as part of a property list specification for the ** 'defalias' records a more precise history of definitions. This is recorded in the `function-history` symbol property. +--- +** 'indian-tml-base-table' no longer translates digits. +Use 'indian-tml-base-digits-table' if you want digits translation. + +-- +** 'indian-tml-itrans-v5-hash' no longer translates digits. +Use 'indian-tml-itrans-digits-v5-hash' if you digits translation. * Changes in Emacs 29.1 on Non-Free Operating Systems diff --git a/lisp/language/ind-util.el b/lisp/language/ind-util.el index 8b1c3d69ae..60ada03fa2 100644 --- a/lisp/language/ind-util.el +++ b/lisp/language/ind-util.el @@ -255,6 +255,29 @@ "ണ്" ?ൺ "ന്" ?ൻ "ര്" ?ർ "ല്" ?ൽ "ള്" ?ൾ))) (defvar indian-tml-base-table + '( + (;; VOWELS + (?அ nil) (?ஆ ?ா) (?இ ?ி) (?ஈ ?ீ) (?உ ?ு) (?ஊ ?ூ) + nil nil nil (?ஏ ?ே) (?எ ?ெ) (?ஐ ?ை) + nil (?ஓ ?ோ) (?ஒ ?ொ) (?ஔ ?ௌ) nil nil) + (;; CONSONANTS + ?க nil nil nil ?ங ;; GUTTRULS + ?ச nil ?ஜ nil ?ஞ ;; PALATALS + ?ட nil nil nil ?ண ;; CEREBRALS + ?த nil nil nil ?ந ?ன ;; DENTALS + ?ப nil nil nil ?ம ;; LABIALS + ?ய ?ர ?ற ?ல ?ள ?ழ ?வ ;; SEMIVOWELS + nil ?ஷ ?ஸ ?ஹ ;; SIBILANTS + nil nil nil nil nil nil nil nil ;; NUKTAS + "ஜ்ஞ" "க்ஷ") + (;; Misc Symbols + nil ?ஂ ?ஃ nil ?் nil nil) + (;; Digits + nil nil nil nil nil nil nil nil nil nil) + (;; Inscript-extra (4) (#, $, ^, *, ]) + "்ர" "ர்" "த்ர" nil nil))) + +(defvar indian-tml-base-digits-table '( (;; VOWELS (?அ nil) (?ஆ ?ா) (?இ ?ி) (?ஈ ?ீ) (?உ ?ு) (?ஊ ?ூ) @@ -557,6 +580,10 @@ (defvar indian-tml-itrans-v5-hash (indian-make-hash indian-tml-base-table indian-itrans-v5-table-for-tamil)) + +(defvar indian-tml-itrans-digits-v5-hash + (indian-make-hash indian-tml-base-digits-table + indian-itrans-v5-table-for-tamil)) ) (defmacro indian-translate-region (from to hashtable encode-p) diff --git a/lisp/leim/quail/indian.el b/lisp/leim/quail/indian.el index 23204c0cd3..6641aa6b2e 100644 --- a/lisp/leim/quail/indian.el +++ b/lisp/leim/quail/indian.el @@ -171,7 +171,7 @@ clm) (with-temp-buffer (insert "\n") - (insert " +") + (insert "----+") (insert-char ?- 74) (insert "\n |") (setq clm 6) @@ -244,19 +244,27 @@ (insert "\n") (buffer-string)))) -(defvar quail-tamil-itrans-various-signs-and-digits-table +(defun quail-tamil-itrans-compute-signs-table (digitp) + "Compute the signs table for the tamil-itrans input method. +If DIGITP is non-nil, include the digits translation as well." (let ((various '((?ஃ . "H") ("ஸ்ரீ" . "srii") (?ௐ))) (digits "௦௧௨௩௪௫௬௭௮௯") (width 6) clm) (with-temp-buffer - (insert "\n" (make-string 18 ?-) "+" (make-string 60 ?-) "\n") + (insert "\n" (make-string 18 ?-) "+") + (when digitp (insert (make-string 60 ?-))) + (insert "\n") (insert (propertize "\t" 'display '(space :align-to 5)) "various" - (propertize "\t" 'display '(space :align-to 18)) "|" - (propertize "\t" 'display '(space :align-to 45)) "digits") - - (insert "\n" (make-string 18 ?-) "+" (make-string 60 ?-) "\n") - (setq clm 0 ) + (propertize "\t" 'display '(space :align-to 18)) "|") + (when digitp + (insert + (propertize "\t" 'display '(space :align-to 45)) "digits")) + (insert "\n" (make-string 18 ?-) "+") + (when digitp + (insert (make-string 60 ?-))) + (insert "\n") + (setq clm 0) (dotimes (i (length various)) (insert (propertize "\t" 'display (list 'space :align-to clm)) @@ -264,10 +272,11 @@ (setq clm (+ clm width))) (insert (propertize "\t" 'display '(space :align-to 18)) "|") (setq clm 20) - (dotimes (i 10) - (insert (propertize "\t" 'display (list 'space :align-to clm)) - (aref digits i)) - (setq clm (+ clm width))) + (when digitp + (dotimes (i 10) + (insert (propertize "\t" 'display (list 'space :align-to clm)) + (aref digits i)) + (setq clm (+ clm width)))) (insert "\n") (setq clm 0) (dotimes (i (length various)) @@ -276,13 +285,22 @@ (setq clm (+ clm width))) (insert (propertize "\t" 'display '(space :align-to 18)) "|") (setq clm 20) - (dotimes (i 10) - (insert (propertize "\t" 'display (list 'space :align-to clm)) - (format "%d" i)) - (setq clm (+ clm width))) - (insert "\n" (make-string 18 ?-) "+" (make-string 60 ?-) "\n") + (when digitp + (dotimes (i 10) + (insert (propertize "\t" 'display (list 'space :align-to clm)) + (format "%d" i)) + (setq clm (+ clm width)))) + (insert "\n" (make-string 18 ?-) "+") + (when digitp + (insert (make-string 60 ?-) "\n")) (buffer-string)))) +(defvar quail-tamil-itrans-various-signs-and-digits-table + (quail-tamil-itrans-compute-signs-table t)) + +(defvar quail-tamil-itrans-various-signs-table + (quail-tamil-itrans-compute-signs-table nil)) + (if nil (quail-define-package "tamil-itrans" "Tamil" "TmlIT" t "Tamil ITRANS")) (quail-define-indian-trans-package @@ -293,16 +311,39 @@ You can input characters using the following mapping tables. Example: To enter வணக்கம், type vaNakkam. ### Basic syllables (consonants + vowels) ### -\\ +\\=\\ + +### Miscellaneous (various signs) ### +\\=\\ + +### Others (numerics + symbols) ### + +Characters below have no ITRANS method associated with them. +Their descriptions are included for easy reference. +\\=\\ + +Full key sequences are listed below:") + +(if nil + (quail-define-package "tamil-itrans-digits" "Tamil" "TmlITD" t "Tamil ITRANS with digits")) +(quail-define-indian-trans-package + indian-tml-itrans-digits-v5-hash "tamil-itrans-digits" "Tamil" "TmlITD" + "Tamil transliteration by ITRANS method with Tamil digits support. + +You can input characters using the following mapping tables. + Example: To enter வணக்கம், type vaNakkam. + +### Basic syllables (consonants + vowels) ### +\\=\\ ### Miscellaneous (various signs + digits) ### -\\ +\\=\\ ### Others (numerics + symbols) ### Characters below have no ITRANS method associated with them. Their descriptions are included for easy reference. -\\ +\\=\\ Full key sequences are listed below:") @@ -479,6 +520,13 @@ Full key sequences are listed below:") "tamil-inscript" "Tamil" "TmlIS" "Tamil keyboard Inscript.") +(if nil + (quail-define-package "tamil-inscript-digits" "Tamil" "TmlISD" t "Tamil keyboard Inscript with digits.")) +(quail-define-inscript-package + indian-tml-base-digits-table inscript-tml-keytable + "tamil-inscript-digits" "Tamil" "TmlISD" + "Tamil keyboard Inscript with Tamil digits support.") + ;; Probhat Input Method (quail-define-package "bengali-probhat" "Bengali" "BngPB" t commit 1ec40630171c90203d7deafe2086d5bd728d790b Author: Eli Zaretskii Date: Sun Mar 13 09:53:59 2022 +0200 ; * admin/make-tarball.txt: Minor updates. diff --git a/admin/make-tarball.txt b/admin/make-tarball.txt index 872cb00ca2..ec69302dae 100644 --- a/admin/make-tarball.txt +++ b/admin/make-tarball.txt @@ -43,11 +43,16 @@ General steps (for each step, check for possible errors): because some of the commands below run Make, so they need Makefiles to be present. - For Emacs 28, and as long as --with-native-compilation is not the - default, the tree needs to be configured with native-compilation - enabled, to ensure all the pertinent *.elc files will end up in - the tarball. Otherwise, the *.eln files might not build correctly - on the user's system. + For Emacs 28 and later, as long as --with-native-compilation is + not the default, the tree needs to be configured with + native-compilation enabled, to ensure all the pertinent *.elc + files will end up in the tarball. Otherwise, the *.eln files + might not build correctly on the user's system. + + For a release (as opposed to pretest), delete any left-over "---" + and "+++" markers from etc/NEWS, as well as the "Temporary note" + section at the beginning of that file, and commit etc/NEWS if it + was modified. 2. Regenerate the etc/AUTHORS file: M-: (require 'authors) RET @@ -232,7 +237,9 @@ General steps (for each step, check for possible errors): FILE.gz FILE.xz ... You only need the --user part if you have multiple GPG keys and do - not want to use the default. + not want to use the default. Instead of "your@gpg.key.email" you + could also use the fingerprint of the key, a 40-digit hex number. + (Alternatively, define default-key in your ~/.gnupg/gpg.conf file.) Obviously, if you do not have a fast uplink, be prepared for the upload to take a while.