diff options
| author | Eli Zaretskii | 2011-08-05 14:04:44 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2011-08-05 14:04:44 +0300 |
| commit | 5009803bda518652cc6f4b9fba02c0aed185c2a3 (patch) | |
| tree | 5d0443887455129a793cadd52f03f740ec5230da /src | |
| parent | e2e2423bf2fe3cda60737f20aeafaff64d38b35e (diff) | |
| parent | 35928349678bc6ed8f621fe7d4da6a9a3fb3579d (diff) | |
| download | emacs-5009803bda518652cc6f4b9fba02c0aed185c2a3.tar.gz emacs-5009803bda518652cc6f4b9fba02c0aed185c2a3.zip | |
Fix bug #9221 with memory leak in bidi display.
Add code to monitor memory allocation for bidi cache shelving.
src/xdisp.c (display_line): Release buffer allocated for shelved bidi
cache.
src/bidi.c (bidi_shelve_cache, bidi_unshelve_cache): Track total
amount allocated this far in `bidi_cache_total_alloc'.
(bidi_unshelve_cache): Accept an additional argument JUST_FREE; if
non-zero, only free the data buffer without restoring the cache
contents. All callers changed.
src/dispextern.h (bidi_unshelve_cache): Update prototype.
src/xdisp.c (SAVE_IT, pos_visible_p, move_it_in_display_line_to)
(move_it_in_display_line, move_it_to)
(move_it_vertically_backward, move_it_by_lines): Replace the call
to xfree to an equivalent call to bidi_unshelve_cache.
(move_it_in_display_line_to): Fix logic of returning
MOVE_POS_MATCH_OR_ZV in the bidi case.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 20 | ||||
| -rw-r--r-- | src/bidi.c | 76 | ||||
| -rw-r--r-- | src/dispextern.h | 2 | ||||
| -rw-r--r-- | src/dispnew.c | 2 | ||||
| -rw-r--r-- | src/indent.c | 2 | ||||
| -rw-r--r-- | src/window.c | 18 | ||||
| -rw-r--r-- | src/xdisp.c | 53 |
7 files changed, 110 insertions, 63 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 5861ee6c48b..3ac958e0311 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,25 @@ | |||
| 1 | 2011-08-05 Eli Zaretskii <eliz@gnu.org> | 1 | 2011-08-05 Eli Zaretskii <eliz@gnu.org> |
| 2 | 2 | ||
| 3 | *xdisp.c (display_line): Release buffer allocated for shelved bidi | ||
| 4 | cache. (Bug#9221) | ||
| 5 | |||
| 6 | * bidi.c (bidi_shelve_cache, bidi_unshelve_cache): Track total | ||
| 7 | amount allocated this far in `bidi_cache_total_alloc'. | ||
| 8 | (bidi_unshelve_cache): Accept an additional argument JUST_FREE; if | ||
| 9 | non-zero, only free the data buffer without restoring the cache | ||
| 10 | contents. All callers changed. | ||
| 11 | |||
| 12 | * dispextern.h (bidi_unshelve_cache): Update prototype. | ||
| 13 | |||
| 14 | * xdisp.c (SAVE_IT, pos_visible_p, move_it_in_display_line_to) | ||
| 15 | (move_it_in_display_line, move_it_to) | ||
| 16 | (move_it_vertically_backward, move_it_by_lines): Replace the call | ||
| 17 | to xfree to an equivalent call to bidi_unshelve_cache. | ||
| 18 | (move_it_in_display_line_to): Fix logic of returning | ||
| 19 | MOVE_POS_MATCH_OR_ZV in the bidi case. | ||
| 20 | |||
| 21 | 2011-08-05 Eli Zaretskii <eliz@gnu.org> | ||
| 22 | |||
| 3 | * xdisp.c (set_cursor_from_row): Prefer the candidate glyph that | 23 | * xdisp.c (set_cursor_from_row): Prefer the candidate glyph that |
| 4 | came from a string character with a `cursor' property. (Bug#9229) | 24 | came from a string character with a `cursor' property. (Bug#9229) |
| 5 | 25 | ||
diff --git a/src/bidi.c b/src/bidi.c index ae5143b37e0..00a6aeef954 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -620,12 +620,15 @@ bidi_pop_it (struct bidi_it *bidi_it) | |||
| 620 | bidi_cache_last_idx = -1; | 620 | bidi_cache_last_idx = -1; |
| 621 | } | 621 | } |
| 622 | 622 | ||
| 623 | ptrdiff_t bidi_cache_total_alloc; | ||
| 624 | |||
| 623 | /* Stash away a copy of the cache and its control variables. */ | 625 | /* Stash away a copy of the cache and its control variables. */ |
| 624 | void * | 626 | void * |
| 625 | bidi_shelve_cache (void) | 627 | bidi_shelve_cache (void) |
| 626 | { | 628 | { |
| 627 | unsigned char *databuf; | 629 | unsigned char *databuf; |
| 628 | 630 | ||
| 631 | /* Empty cache. */ | ||
| 629 | if (bidi_cache_idx == 0) | 632 | if (bidi_cache_idx == 0) |
| 630 | return NULL; | 633 | return NULL; |
| 631 | 634 | ||
| @@ -634,6 +637,12 @@ bidi_shelve_cache (void) | |||
| 634 | + sizeof (bidi_cache_start_stack) | 637 | + sizeof (bidi_cache_start_stack) |
| 635 | + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) | 638 | + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) |
| 636 | + sizeof (bidi_cache_last_idx)); | 639 | + sizeof (bidi_cache_last_idx)); |
| 640 | bidi_cache_total_alloc += | ||
| 641 | sizeof (bidi_cache_idx) + bidi_cache_idx * sizeof (struct bidi_it) | ||
| 642 | + sizeof (bidi_cache_start_stack) | ||
| 643 | + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) | ||
| 644 | + sizeof (bidi_cache_last_idx); | ||
| 645 | |||
| 637 | memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx)); | 646 | memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx)); |
| 638 | memcpy (databuf + sizeof (bidi_cache_idx), | 647 | memcpy (databuf + sizeof (bidi_cache_idx), |
| 639 | bidi_cache, bidi_cache_idx * sizeof (struct bidi_it)); | 648 | bidi_cache, bidi_cache_idx * sizeof (struct bidi_it)); |
| @@ -659,7 +668,7 @@ bidi_shelve_cache (void) | |||
| 659 | 668 | ||
| 660 | /* Restore the cache state from a copy stashed away by bidi_shelve_cache. */ | 669 | /* Restore the cache state from a copy stashed away by bidi_shelve_cache. */ |
| 661 | void | 670 | void |
| 662 | bidi_unshelve_cache (void *databuf) | 671 | bidi_unshelve_cache (void *databuf, int just_free) |
| 663 | { | 672 | { |
| 664 | unsigned char *p = databuf; | 673 | unsigned char *p = databuf; |
| 665 | 674 | ||
| @@ -672,30 +681,47 @@ bidi_unshelve_cache (void *databuf) | |||
| 672 | } | 681 | } |
| 673 | else | 682 | else |
| 674 | { | 683 | { |
| 675 | memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx)); | 684 | if (just_free) |
| 676 | bidi_cache_ensure_space (bidi_cache_idx); | 685 | { |
| 677 | memcpy (bidi_cache, p + sizeof (bidi_cache_idx), | 686 | ptrdiff_t idx; |
| 678 | bidi_cache_idx * sizeof (struct bidi_it)); | 687 | |
| 679 | memcpy (bidi_cache_start_stack, | 688 | memcpy (&idx, p, sizeof (bidi_cache_idx)); |
| 680 | p + sizeof (bidi_cache_idx) | 689 | bidi_cache_total_alloc -= |
| 681 | + bidi_cache_idx * sizeof (struct bidi_it), | 690 | sizeof (bidi_cache_idx) + idx * sizeof (struct bidi_it) |
| 682 | sizeof (bidi_cache_start_stack)); | 691 | + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) |
| 683 | memcpy (&bidi_cache_sp, | 692 | + sizeof (bidi_cache_start) + sizeof (bidi_cache_last_idx); |
| 684 | p + sizeof (bidi_cache_idx) | 693 | } |
| 685 | + bidi_cache_idx * sizeof (struct bidi_it) | 694 | else |
| 686 | + sizeof (bidi_cache_start_stack), | 695 | { |
| 687 | sizeof (bidi_cache_sp)); | 696 | memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx)); |
| 688 | memcpy (&bidi_cache_start, | 697 | bidi_cache_ensure_space (bidi_cache_idx); |
| 689 | p + sizeof (bidi_cache_idx) | 698 | memcpy (bidi_cache, p + sizeof (bidi_cache_idx), |
| 690 | + bidi_cache_idx * sizeof (struct bidi_it) | 699 | bidi_cache_idx * sizeof (struct bidi_it)); |
| 691 | + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp), | 700 | memcpy (bidi_cache_start_stack, |
| 692 | sizeof (bidi_cache_start)); | 701 | p + sizeof (bidi_cache_idx) |
| 693 | memcpy (&bidi_cache_last_idx, | 702 | + bidi_cache_idx * sizeof (struct bidi_it), |
| 694 | p + sizeof (bidi_cache_idx) | 703 | sizeof (bidi_cache_start_stack)); |
| 695 | + bidi_cache_idx * sizeof (struct bidi_it) | 704 | memcpy (&bidi_cache_sp, |
| 696 | + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) | 705 | p + sizeof (bidi_cache_idx) |
| 697 | + sizeof (bidi_cache_start), | 706 | + bidi_cache_idx * sizeof (struct bidi_it) |
| 698 | sizeof (bidi_cache_last_idx)); | 707 | + sizeof (bidi_cache_start_stack), |
| 708 | sizeof (bidi_cache_sp)); | ||
| 709 | memcpy (&bidi_cache_start, | ||
| 710 | p + sizeof (bidi_cache_idx) | ||
| 711 | + bidi_cache_idx * sizeof (struct bidi_it) | ||
| 712 | + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp), | ||
| 713 | sizeof (bidi_cache_start)); | ||
| 714 | memcpy (&bidi_cache_last_idx, | ||
| 715 | p + sizeof (bidi_cache_idx) | ||
| 716 | + bidi_cache_idx * sizeof (struct bidi_it) | ||
| 717 | + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) | ||
| 718 | + sizeof (bidi_cache_start), | ||
| 719 | sizeof (bidi_cache_last_idx)); | ||
| 720 | bidi_cache_total_alloc -= | ||
| 721 | sizeof (bidi_cache_idx) + bidi_cache_idx * sizeof (struct bidi_it) | ||
| 722 | + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) | ||
| 723 | + sizeof (bidi_cache_start) + sizeof (bidi_cache_last_idx); | ||
| 724 | } | ||
| 699 | 725 | ||
| 700 | xfree (p); | 726 | xfree (p); |
| 701 | } | 727 | } |
diff --git a/src/dispextern.h b/src/dispextern.h index 2e245479a81..ea4b11baa74 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -2978,7 +2978,7 @@ extern int bidi_mirror_char (int); | |||
| 2978 | extern void bidi_push_it (struct bidi_it *); | 2978 | extern void bidi_push_it (struct bidi_it *); |
| 2979 | extern void bidi_pop_it (struct bidi_it *); | 2979 | extern void bidi_pop_it (struct bidi_it *); |
| 2980 | extern void *bidi_shelve_cache (void); | 2980 | extern void *bidi_shelve_cache (void); |
| 2981 | extern void bidi_unshelve_cache (void *); | 2981 | extern void bidi_unshelve_cache (void *, int); |
| 2982 | 2982 | ||
| 2983 | /* Defined in xdisp.c */ | 2983 | /* Defined in xdisp.c */ |
| 2984 | 2984 | ||
diff --git a/src/dispnew.c b/src/dispnew.c index b2f416701c3..fadfbb26603 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -5282,7 +5282,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p | |||
| 5282 | argument is ZV to prevent move_it_in_display_line from matching | 5282 | argument is ZV to prevent move_it_in_display_line from matching |
| 5283 | based on buffer positions. */ | 5283 | based on buffer positions. */ |
| 5284 | move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X); | 5284 | move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X); |
| 5285 | bidi_unshelve_cache (itdata); | 5285 | bidi_unshelve_cache (itdata, 0); |
| 5286 | 5286 | ||
| 5287 | Fset_buffer (old_current_buffer); | 5287 | Fset_buffer (old_current_buffer); |
| 5288 | 5288 | ||
diff --git a/src/indent.c b/src/indent.c index aaeaaf591ef..70689311dd5 100644 --- a/src/indent.c +++ b/src/indent.c | |||
| @@ -2135,7 +2135,7 @@ whether or not it is currently displayed in some window. */) | |||
| 2135 | } | 2135 | } |
| 2136 | 2136 | ||
| 2137 | SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); | 2137 | SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); |
| 2138 | bidi_unshelve_cache (itdata); | 2138 | bidi_unshelve_cache (itdata, 0); |
| 2139 | } | 2139 | } |
| 2140 | 2140 | ||
| 2141 | if (BUFFERP (old_buffer)) | 2141 | if (BUFFERP (old_buffer)) |
diff --git a/src/window.c b/src/window.c index 3f5a743f5c6..8df4a857851 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -1379,7 +1379,7 @@ if it isn't already recorded. */) | |||
| 1379 | if (it.current_y < it.last_visible_y) | 1379 | if (it.current_y < it.last_visible_y) |
| 1380 | move_it_past_eol (&it); | 1380 | move_it_past_eol (&it); |
| 1381 | value = make_number (IT_CHARPOS (it)); | 1381 | value = make_number (IT_CHARPOS (it)); |
| 1382 | bidi_unshelve_cache (itdata); | 1382 | bidi_unshelve_cache (itdata, 0); |
| 1383 | 1383 | ||
| 1384 | if (old_buffer) | 1384 | if (old_buffer) |
| 1385 | set_buffer_internal (old_buffer); | 1385 | set_buffer_internal (old_buffer); |
| @@ -4273,7 +4273,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4273 | } | 4273 | } |
| 4274 | 4274 | ||
| 4275 | start = it.current.pos; | 4275 | start = it.current.pos; |
| 4276 | bidi_unshelve_cache (itdata); | 4276 | bidi_unshelve_cache (itdata, 0); |
| 4277 | } | 4277 | } |
| 4278 | else if (auto_window_vscroll_p) | 4278 | else if (auto_window_vscroll_p) |
| 4279 | { | 4279 | { |
| @@ -4417,7 +4417,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4417 | } | 4417 | } |
| 4418 | else | 4418 | else |
| 4419 | { | 4419 | { |
| 4420 | bidi_unshelve_cache (itdata); | 4420 | bidi_unshelve_cache (itdata, 0); |
| 4421 | if (noerror) | 4421 | if (noerror) |
| 4422 | return; | 4422 | return; |
| 4423 | else if (n < 0) /* could happen with empty buffers */ | 4423 | else if (n < 0) /* could happen with empty buffers */ |
| @@ -4434,7 +4434,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4434 | w->vscroll = 0; | 4434 | w->vscroll = 0; |
| 4435 | else | 4435 | else |
| 4436 | { | 4436 | { |
| 4437 | bidi_unshelve_cache (itdata); | 4437 | bidi_unshelve_cache (itdata, 0); |
| 4438 | if (noerror) | 4438 | if (noerror) |
| 4439 | return; | 4439 | return; |
| 4440 | else | 4440 | else |
| @@ -4583,7 +4583,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4583 | SET_PT_BOTH (charpos, bytepos); | 4583 | SET_PT_BOTH (charpos, bytepos); |
| 4584 | } | 4584 | } |
| 4585 | } | 4585 | } |
| 4586 | bidi_unshelve_cache (itdata); | 4586 | bidi_unshelve_cache (itdata, 0); |
| 4587 | } | 4587 | } |
| 4588 | 4588 | ||
| 4589 | 4589 | ||
| @@ -5010,7 +5010,7 @@ displayed_window_lines (struct window *w) | |||
| 5010 | start_display (&it, w, start); | 5010 | start_display (&it, w, start); |
| 5011 | move_it_vertically (&it, height); | 5011 | move_it_vertically (&it, height); |
| 5012 | bottom_y = line_bottom_y (&it); | 5012 | bottom_y = line_bottom_y (&it); |
| 5013 | bidi_unshelve_cache (itdata); | 5013 | bidi_unshelve_cache (itdata, 0); |
| 5014 | 5014 | ||
| 5015 | /* rms: On a non-window display, | 5015 | /* rms: On a non-window display, |
| 5016 | the value of it.vpos at the bottom of the screen | 5016 | the value of it.vpos at the bottom of the screen |
| @@ -5116,7 +5116,7 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5116 | move_it_vertically_backward (&it, window_box_height (w) / 2); | 5116 | move_it_vertically_backward (&it, window_box_height (w) / 2); |
| 5117 | charpos = IT_CHARPOS (it); | 5117 | charpos = IT_CHARPOS (it); |
| 5118 | bytepos = IT_BYTEPOS (it); | 5118 | bytepos = IT_BYTEPOS (it); |
| 5119 | bidi_unshelve_cache (itdata); | 5119 | bidi_unshelve_cache (itdata, 0); |
| 5120 | } | 5120 | } |
| 5121 | else if (iarg < 0) | 5121 | else if (iarg < 0) |
| 5122 | { | 5122 | { |
| @@ -5164,7 +5164,7 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5164 | } | 5164 | } |
| 5165 | if (h <= 0) | 5165 | if (h <= 0) |
| 5166 | { | 5166 | { |
| 5167 | bidi_unshelve_cache (itdata); | 5167 | bidi_unshelve_cache (itdata, 0); |
| 5168 | return Qnil; | 5168 | return Qnil; |
| 5169 | } | 5169 | } |
| 5170 | 5170 | ||
| @@ -5187,7 +5187,7 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5187 | charpos = IT_CHARPOS (it); | 5187 | charpos = IT_CHARPOS (it); |
| 5188 | bytepos = IT_BYTEPOS (it); | 5188 | bytepos = IT_BYTEPOS (it); |
| 5189 | 5189 | ||
| 5190 | bidi_unshelve_cache (itdata); | 5190 | bidi_unshelve_cache (itdata, 0); |
| 5191 | } | 5191 | } |
| 5192 | else | 5192 | else |
| 5193 | { | 5193 | { |
diff --git a/src/xdisp.c b/src/xdisp.c index 59a6bc3f906..69baea95b9c 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -604,7 +604,7 @@ int current_mode_line_height, current_header_line_height; | |||
| 604 | #define SAVE_IT(ITCOPY,ITORIG,CACHE) \ | 604 | #define SAVE_IT(ITCOPY,ITORIG,CACHE) \ |
| 605 | do { \ | 605 | do { \ |
| 606 | if (CACHE) \ | 606 | if (CACHE) \ |
| 607 | xfree (CACHE); \ | 607 | bidi_unshelve_cache (CACHE, 1); \ |
| 608 | ITCOPY = ITORIG; \ | 608 | ITCOPY = ITORIG; \ |
| 609 | CACHE = bidi_shelve_cache(); \ | 609 | CACHE = bidi_shelve_cache(); \ |
| 610 | } while (0) | 610 | } while (0) |
| @@ -613,7 +613,7 @@ int current_mode_line_height, current_header_line_height; | |||
| 613 | do { \ | 613 | do { \ |
| 614 | if (pITORIG != pITCOPY) \ | 614 | if (pITORIG != pITCOPY) \ |
| 615 | *(pITORIG) = *(pITCOPY); \ | 615 | *(pITORIG) = *(pITCOPY); \ |
| 616 | bidi_unshelve_cache (CACHE); \ | 616 | bidi_unshelve_cache (CACHE, 0); \ |
| 617 | CACHE = NULL; \ | 617 | CACHE = NULL; \ |
| 618 | } while (0) | 618 | } while (0) |
| 619 | 619 | ||
| @@ -1341,9 +1341,9 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y, | |||
| 1341 | *vpos = it2.vpos; | 1341 | *vpos = it2.vpos; |
| 1342 | } | 1342 | } |
| 1343 | else | 1343 | else |
| 1344 | xfree (it2data); | 1344 | bidi_unshelve_cache (it2data, 1); |
| 1345 | } | 1345 | } |
| 1346 | bidi_unshelve_cache (itdata); | 1346 | bidi_unshelve_cache (itdata, 0); |
| 1347 | 1347 | ||
| 1348 | if (old_buffer) | 1348 | if (old_buffer) |
| 1349 | set_buffer_internal_1 (old_buffer); | 1349 | set_buffer_internal_1 (old_buffer); |
| @@ -2627,7 +2627,7 @@ init_iterator (struct it *it, struct window *w, | |||
| 2627 | it->paragraph_embedding = R2L; | 2627 | it->paragraph_embedding = R2L; |
| 2628 | else | 2628 | else |
| 2629 | it->paragraph_embedding = NEUTRAL_DIR; | 2629 | it->paragraph_embedding = NEUTRAL_DIR; |
| 2630 | bidi_unshelve_cache (NULL); | 2630 | bidi_unshelve_cache (NULL, 0); |
| 2631 | bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), | 2631 | bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), |
| 2632 | &it->bidi_it); | 2632 | &it->bidi_it); |
| 2633 | } | 2633 | } |
| @@ -5618,7 +5618,7 @@ back_to_previous_visible_line_start (struct it *it) | |||
| 5618 | pos = --IT_CHARPOS (it2); | 5618 | pos = --IT_CHARPOS (it2); |
| 5619 | --IT_BYTEPOS (it2); | 5619 | --IT_BYTEPOS (it2); |
| 5620 | it2.sp = 0; | 5620 | it2.sp = 0; |
| 5621 | bidi_unshelve_cache (NULL); | 5621 | bidi_unshelve_cache (NULL, 0); |
| 5622 | it2.string_from_display_prop_p = 0; | 5622 | it2.string_from_display_prop_p = 0; |
| 5623 | it2.from_disp_prop_p = 0; | 5623 | it2.from_disp_prop_p = 0; |
| 5624 | if (handle_display_prop (&it2) == HANDLED_RETURN | 5624 | if (handle_display_prop (&it2) == HANDLED_RETURN |
| @@ -5828,7 +5828,7 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p) | |||
| 5828 | { | 5828 | { |
| 5829 | bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), | 5829 | bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), |
| 5830 | &it->bidi_it); | 5830 | &it->bidi_it); |
| 5831 | bidi_unshelve_cache (NULL); | 5831 | bidi_unshelve_cache (NULL, 0); |
| 5832 | it->bidi_it.paragraph_dir = NEUTRAL_DIR; | 5832 | it->bidi_it.paragraph_dir = NEUTRAL_DIR; |
| 5833 | it->bidi_it.string.s = NULL; | 5833 | it->bidi_it.string.s = NULL; |
| 5834 | it->bidi_it.string.lstring = Qnil; | 5834 | it->bidi_it.string.lstring = Qnil; |
| @@ -8009,13 +8009,13 @@ move_it_in_display_line_to (struct it *it, | |||
| 8009 | positions smaller than TO_CHARPOS, return | 8009 | positions smaller than TO_CHARPOS, return |
| 8010 | MOVE_POS_MATCH_OR_ZV, like the unidirectional display | 8010 | MOVE_POS_MATCH_OR_ZV, like the unidirectional display |
| 8011 | did. */ | 8011 | did. */ |
| 8012 | if ((op & MOVE_TO_POS) != 0 | 8012 | if (it->bidi_p && (op & MOVE_TO_POS) != 0 |
| 8013 | && !saw_smaller_pos | 8013 | && !saw_smaller_pos |
| 8014 | && IT_CHARPOS (*it) > to_charpos) | 8014 | && IT_CHARPOS (*it) > to_charpos) |
| 8015 | { | 8015 | { |
| 8016 | result = MOVE_POS_MATCH_OR_ZV; | 8016 | if (IT_CHARPOS (ppos_it) < ZV) |
| 8017 | if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV) | ||
| 8018 | RESTORE_IT (it, &ppos_it, ppos_data); | 8017 | RESTORE_IT (it, &ppos_it, ppos_data); |
| 8018 | goto buffer_pos_reached; | ||
| 8019 | } | 8019 | } |
| 8020 | else | 8020 | else |
| 8021 | result = MOVE_NEWLINE_OR_CR; | 8021 | result = MOVE_NEWLINE_OR_CR; |
| @@ -8054,14 +8054,13 @@ move_it_in_display_line_to (struct it *it, | |||
| 8054 | character positions smaller than TO_CHARPOS, | 8054 | character positions smaller than TO_CHARPOS, |
| 8055 | return MOVE_POS_MATCH_OR_ZV, like the | 8055 | return MOVE_POS_MATCH_OR_ZV, like the |
| 8056 | unidirectional display did. */ | 8056 | unidirectional display did. */ |
| 8057 | || ((op & MOVE_TO_POS) != 0 | 8057 | || (it->bidi_p && (op & MOVE_TO_POS) != 0 |
| 8058 | && !saw_smaller_pos | 8058 | && !saw_smaller_pos |
| 8059 | && IT_CHARPOS (*it) > to_charpos)) | 8059 | && IT_CHARPOS (*it) > to_charpos)) |
| 8060 | { | 8060 | { |
| 8061 | result = MOVE_POS_MATCH_OR_ZV; | 8061 | if (!at_eob_p && IT_CHARPOS (ppos_it) < ZV) |
| 8062 | if (it->bidi_p && !at_eob_p && IT_CHARPOS (ppos_it) < ZV) | ||
| 8063 | RESTORE_IT (it, &ppos_it, ppos_data); | 8062 | RESTORE_IT (it, &ppos_it, ppos_data); |
| 8064 | break; | 8063 | goto buffer_pos_reached; |
| 8065 | } | 8064 | } |
| 8066 | if (ITERATOR_AT_END_OF_LINE_P (it)) | 8065 | if (ITERATOR_AT_END_OF_LINE_P (it)) |
| 8067 | { | 8066 | { |
| @@ -8069,14 +8068,13 @@ move_it_in_display_line_to (struct it *it, | |||
| 8069 | break; | 8068 | break; |
| 8070 | } | 8069 | } |
| 8071 | } | 8070 | } |
| 8072 | else if ((op & MOVE_TO_POS) != 0 | 8071 | else if (it->bidi_p && (op & MOVE_TO_POS) != 0 |
| 8073 | && !saw_smaller_pos | 8072 | && !saw_smaller_pos |
| 8074 | && IT_CHARPOS (*it) > to_charpos) | 8073 | && IT_CHARPOS (*it) > to_charpos) |
| 8075 | { | 8074 | { |
| 8076 | result = MOVE_POS_MATCH_OR_ZV; | 8075 | if (IT_CHARPOS (ppos_it) < ZV) |
| 8077 | if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV) | ||
| 8078 | RESTORE_IT (it, &ppos_it, ppos_data); | 8076 | RESTORE_IT (it, &ppos_it, ppos_data); |
| 8079 | break; | 8077 | goto buffer_pos_reached; |
| 8080 | } | 8078 | } |
| 8081 | result = MOVE_LINE_TRUNCATED; | 8079 | result = MOVE_LINE_TRUNCATED; |
| 8082 | break; | 8080 | break; |
| @@ -8096,13 +8094,13 @@ move_it_in_display_line_to (struct it *it, | |||
| 8096 | done: | 8094 | done: |
| 8097 | 8095 | ||
| 8098 | if (atpos_data) | 8096 | if (atpos_data) |
| 8099 | xfree (atpos_data); | 8097 | bidi_unshelve_cache (atpos_data, 1); |
| 8100 | if (atx_data) | 8098 | if (atx_data) |
| 8101 | xfree (atx_data); | 8099 | bidi_unshelve_cache (atx_data, 1); |
| 8102 | if (wrap_data) | 8100 | if (wrap_data) |
| 8103 | xfree (wrap_data); | 8101 | bidi_unshelve_cache (wrap_data, 1); |
| 8104 | if (ppos_data) | 8102 | if (ppos_data) |
| 8105 | xfree (ppos_data); | 8103 | bidi_unshelve_cache (ppos_data, 1); |
| 8106 | 8104 | ||
| 8107 | /* Restore the iterator settings altered at the beginning of this | 8105 | /* Restore the iterator settings altered at the beginning of this |
| 8108 | function. */ | 8106 | function. */ |
| @@ -8137,7 +8135,7 @@ move_it_in_display_line (struct it *it, | |||
| 8137 | (it, -1, prev_x, MOVE_TO_X); | 8135 | (it, -1, prev_x, MOVE_TO_X); |
| 8138 | } | 8136 | } |
| 8139 | else | 8137 | else |
| 8140 | xfree (save_data); | 8138 | bidi_unshelve_cache (save_data, 1); |
| 8141 | } | 8139 | } |
| 8142 | else | 8140 | else |
| 8143 | move_it_in_display_line_to (it, to_charpos, to_x, op); | 8141 | move_it_in_display_line_to (it, to_charpos, to_x, op); |
| @@ -8396,7 +8394,7 @@ move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos | |||
| 8396 | } | 8394 | } |
| 8397 | 8395 | ||
| 8398 | if (backup_data) | 8396 | if (backup_data) |
| 8399 | xfree (backup_data); | 8397 | bidi_unshelve_cache (backup_data, 1); |
| 8400 | 8398 | ||
| 8401 | TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached)); | 8399 | TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached)); |
| 8402 | } | 8400 | } |
| @@ -8475,7 +8473,7 @@ move_it_vertically_backward (struct it *it, int dy) | |||
| 8475 | RESTORE_IT (it, it, it2data); | 8473 | RESTORE_IT (it, it, it2data); |
| 8476 | if (nlines > 0) | 8474 | if (nlines > 0) |
| 8477 | move_it_by_lines (it, nlines); | 8475 | move_it_by_lines (it, nlines); |
| 8478 | xfree (it3data); | 8476 | bidi_unshelve_cache (it3data, 1); |
| 8479 | } | 8477 | } |
| 8480 | else | 8478 | else |
| 8481 | { | 8479 | { |
| @@ -8671,7 +8669,7 @@ move_it_by_lines (struct it *it, int dvpos) | |||
| 8671 | if (IT_CHARPOS (*it) >= start_charpos) | 8669 | if (IT_CHARPOS (*it) >= start_charpos) |
| 8672 | RESTORE_IT (it, &it2, it2data); | 8670 | RESTORE_IT (it, &it2, it2data); |
| 8673 | else | 8671 | else |
| 8674 | xfree (it2data); | 8672 | bidi_unshelve_cache (it2data, 1); |
| 8675 | } | 8673 | } |
| 8676 | else | 8674 | else |
| 8677 | RESTORE_IT (it, it, it2data); | 8675 | RESTORE_IT (it, it, it2data); |
| @@ -18779,6 +18777,9 @@ display_line (struct it *it) | |||
| 18779 | } | 18777 | } |
| 18780 | } | 18778 | } |
| 18781 | 18779 | ||
| 18780 | if (wrap_data) | ||
| 18781 | bidi_unshelve_cache (wrap_data, 1); | ||
| 18782 | |||
| 18782 | /* If line is not empty and hscrolled, maybe insert truncation glyphs | 18783 | /* If line is not empty and hscrolled, maybe insert truncation glyphs |
| 18783 | at the left window margin. */ | 18784 | at the left window margin. */ |
| 18784 | if (it->first_visible_x | 18785 | if (it->first_visible_x |