diff options
| author | Eli Zaretskii | 2011-08-05 13:48:37 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2011-08-05 13:48:37 +0300 |
| commit | 35928349678bc6ed8f621fe7d4da6a9a3fb3579d (patch) | |
| tree | 57238a3de3ab2aed53b463a06b866ca2811d878f /src | |
| parent | 7daee9109e1d69d62528f6b460d101e1ea44f4e1 (diff) | |
| download | emacs-35928349678bc6ed8f621fe7d4da6a9a3fb3579d.tar.gz emacs-35928349678bc6ed8f621fe7d4da6a9a3fb3579d.zip | |
Fix bug #9221 with resource allocation under word-wrap.
Add diagnostic facility for monitoring memory allocated for cache shelving.
src/xdisp.c (display_line): Release buffer allocated for shelved bidi
cache. (Bug#9221)
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 8aa1237f693..481e5e1ce02 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,23 @@ | |||
| 1 | 2011-08-05 Eli Zaretskii <eliz@gnu.org> | ||
| 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 | |||
| 1 | 2011-07-24 Eli Zaretskii <eliz@gnu.org> | 21 | 2011-07-24 Eli Zaretskii <eliz@gnu.org> |
| 2 | 22 | ||
| 3 | * xdisp.c (compute_display_string_pos): Fix logic of caching | 23 | * xdisp.c (compute_display_string_pos): Fix logic of caching |
diff --git a/src/bidi.c b/src/bidi.c index 77043d9236f..a2ba60a7baf 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -609,12 +609,15 @@ bidi_pop_it (struct bidi_it *bidi_it) | |||
| 609 | bidi_cache_last_idx = -1; | 609 | bidi_cache_last_idx = -1; |
| 610 | } | 610 | } |
| 611 | 611 | ||
| 612 | ptrdiff_t bidi_cache_total_alloc; | ||
| 613 | |||
| 612 | /* Stash away a copy of the cache and its control variables. */ | 614 | /* Stash away a copy of the cache and its control variables. */ |
| 613 | void * | 615 | void * |
| 614 | bidi_shelve_cache (void) | 616 | bidi_shelve_cache (void) |
| 615 | { | 617 | { |
| 616 | unsigned char *databuf; | 618 | unsigned char *databuf; |
| 617 | 619 | ||
| 620 | /* Empty cache. */ | ||
| 618 | if (bidi_cache_idx == 0) | 621 | if (bidi_cache_idx == 0) |
| 619 | return NULL; | 622 | return NULL; |
| 620 | 623 | ||
| @@ -623,6 +626,12 @@ bidi_shelve_cache (void) | |||
| 623 | + sizeof (bidi_cache_start_stack) | 626 | + sizeof (bidi_cache_start_stack) |
| 624 | + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) | 627 | + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) |
| 625 | + sizeof (bidi_cache_last_idx)); | 628 | + sizeof (bidi_cache_last_idx)); |
| 629 | bidi_cache_total_alloc += | ||
| 630 | sizeof (bidi_cache_idx) + bidi_cache_idx * sizeof (struct bidi_it) | ||
| 631 | + sizeof (bidi_cache_start_stack) | ||
| 632 | + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) | ||
| 633 | + sizeof (bidi_cache_last_idx); | ||
| 634 | |||
| 626 | memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx)); | 635 | memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx)); |
| 627 | memcpy (databuf + sizeof (bidi_cache_idx), | 636 | memcpy (databuf + sizeof (bidi_cache_idx), |
| 628 | bidi_cache, bidi_cache_idx * sizeof (struct bidi_it)); | 637 | bidi_cache, bidi_cache_idx * sizeof (struct bidi_it)); |
| @@ -648,7 +657,7 @@ bidi_shelve_cache (void) | |||
| 648 | 657 | ||
| 649 | /* Restore the cache state from a copy stashed away by bidi_shelve_cache. */ | 658 | /* Restore the cache state from a copy stashed away by bidi_shelve_cache. */ |
| 650 | void | 659 | void |
| 651 | bidi_unshelve_cache (void *databuf) | 660 | bidi_unshelve_cache (void *databuf, int just_free) |
| 652 | { | 661 | { |
| 653 | unsigned char *p = databuf; | 662 | unsigned char *p = databuf; |
| 654 | 663 | ||
| @@ -661,30 +670,47 @@ bidi_unshelve_cache (void *databuf) | |||
| 661 | } | 670 | } |
| 662 | else | 671 | else |
| 663 | { | 672 | { |
| 664 | memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx)); | 673 | if (just_free) |
| 665 | bidi_cache_ensure_space (bidi_cache_idx); | 674 | { |
| 666 | memcpy (bidi_cache, p + sizeof (bidi_cache_idx), | 675 | ptrdiff_t idx; |
| 667 | bidi_cache_idx * sizeof (struct bidi_it)); | 676 | |
| 668 | memcpy (bidi_cache_start_stack, | 677 | memcpy (&idx, p, sizeof (bidi_cache_idx)); |
| 669 | p + sizeof (bidi_cache_idx) | 678 | bidi_cache_total_alloc -= |
| 670 | + bidi_cache_idx * sizeof (struct bidi_it), | 679 | sizeof (bidi_cache_idx) + idx * sizeof (struct bidi_it) |
| 671 | sizeof (bidi_cache_start_stack)); | 680 | + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) |
| 672 | memcpy (&bidi_cache_sp, | 681 | + sizeof (bidi_cache_start) + sizeof (bidi_cache_last_idx); |
| 673 | p + sizeof (bidi_cache_idx) | 682 | } |
| 674 | + bidi_cache_idx * sizeof (struct bidi_it) | 683 | else |
| 675 | + sizeof (bidi_cache_start_stack), | 684 | { |
| 676 | sizeof (bidi_cache_sp)); | 685 | memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx)); |
| 677 | memcpy (&bidi_cache_start, | 686 | bidi_cache_ensure_space (bidi_cache_idx); |
| 678 | p + sizeof (bidi_cache_idx) | 687 | memcpy (bidi_cache, p + sizeof (bidi_cache_idx), |
| 679 | + bidi_cache_idx * sizeof (struct bidi_it) | 688 | bidi_cache_idx * sizeof (struct bidi_it)); |
| 680 | + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp), | 689 | memcpy (bidi_cache_start_stack, |
| 681 | sizeof (bidi_cache_start)); | 690 | p + sizeof (bidi_cache_idx) |
| 682 | memcpy (&bidi_cache_last_idx, | 691 | + bidi_cache_idx * sizeof (struct bidi_it), |
| 683 | p + sizeof (bidi_cache_idx) | 692 | sizeof (bidi_cache_start_stack)); |
| 684 | + bidi_cache_idx * sizeof (struct bidi_it) | 693 | memcpy (&bidi_cache_sp, |
| 685 | + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) | 694 | p + sizeof (bidi_cache_idx) |
| 686 | + sizeof (bidi_cache_start), | 695 | + bidi_cache_idx * sizeof (struct bidi_it) |
| 687 | sizeof (bidi_cache_last_idx)); | 696 | + sizeof (bidi_cache_start_stack), |
| 697 | sizeof (bidi_cache_sp)); | ||
| 698 | memcpy (&bidi_cache_start, | ||
| 699 | p + sizeof (bidi_cache_idx) | ||
| 700 | + bidi_cache_idx * sizeof (struct bidi_it) | ||
| 701 | + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp), | ||
| 702 | sizeof (bidi_cache_start)); | ||
| 703 | memcpy (&bidi_cache_last_idx, | ||
| 704 | p + sizeof (bidi_cache_idx) | ||
| 705 | + bidi_cache_idx * sizeof (struct bidi_it) | ||
| 706 | + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) | ||
| 707 | + sizeof (bidi_cache_start), | ||
| 708 | sizeof (bidi_cache_last_idx)); | ||
| 709 | bidi_cache_total_alloc -= | ||
| 710 | sizeof (bidi_cache_idx) + bidi_cache_idx * sizeof (struct bidi_it) | ||
| 711 | + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) | ||
| 712 | + sizeof (bidi_cache_start) + sizeof (bidi_cache_last_idx); | ||
| 713 | } | ||
| 688 | 714 | ||
| 689 | xfree (p); | 715 | xfree (p); |
| 690 | } | 716 | } |
diff --git a/src/dispextern.h b/src/dispextern.h index 5bb72ff7600..32b4bbfab24 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -2975,7 +2975,7 @@ extern int bidi_mirror_char (int); | |||
| 2975 | extern void bidi_push_it (struct bidi_it *); | 2975 | extern void bidi_push_it (struct bidi_it *); |
| 2976 | extern void bidi_pop_it (struct bidi_it *); | 2976 | extern void bidi_pop_it (struct bidi_it *); |
| 2977 | extern void *bidi_shelve_cache (void); | 2977 | extern void *bidi_shelve_cache (void); |
| 2978 | extern void bidi_unshelve_cache (void *); | 2978 | extern void bidi_unshelve_cache (void *, int); |
| 2979 | 2979 | ||
| 2980 | /* Defined in xdisp.c */ | 2980 | /* Defined in xdisp.c */ |
| 2981 | 2981 | ||
diff --git a/src/dispnew.c b/src/dispnew.c index 69b32a5cd79..64fa5733741 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -5311,7 +5311,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p | |||
| 5311 | argument is ZV to prevent move_it_in_display_line from matching | 5311 | argument is ZV to prevent move_it_in_display_line from matching |
| 5312 | based on buffer positions. */ | 5312 | based on buffer positions. */ |
| 5313 | move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X); | 5313 | move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X); |
| 5314 | bidi_unshelve_cache (itdata); | 5314 | bidi_unshelve_cache (itdata, 0); |
| 5315 | 5315 | ||
| 5316 | Fset_buffer (old_current_buffer); | 5316 | Fset_buffer (old_current_buffer); |
| 5317 | 5317 | ||
diff --git a/src/indent.c b/src/indent.c index a73284c6657..3f7b3efe3b8 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 094cfcfbda3..d733dea5026 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -1190,7 +1190,7 @@ if it isn't already recorded. */) | |||
| 1190 | if (it.current_y < it.last_visible_y) | 1190 | if (it.current_y < it.last_visible_y) |
| 1191 | move_it_past_eol (&it); | 1191 | move_it_past_eol (&it); |
| 1192 | value = make_number (IT_CHARPOS (it)); | 1192 | value = make_number (IT_CHARPOS (it)); |
| 1193 | bidi_unshelve_cache (itdata); | 1193 | bidi_unshelve_cache (itdata, 0); |
| 1194 | 1194 | ||
| 1195 | if (old_buffer) | 1195 | if (old_buffer) |
| 1196 | set_buffer_internal (old_buffer); | 1196 | set_buffer_internal (old_buffer); |
| @@ -4771,7 +4771,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4771 | } | 4771 | } |
| 4772 | 4772 | ||
| 4773 | start = it.current.pos; | 4773 | start = it.current.pos; |
| 4774 | bidi_unshelve_cache (itdata); | 4774 | bidi_unshelve_cache (itdata, 0); |
| 4775 | } | 4775 | } |
| 4776 | else if (auto_window_vscroll_p) | 4776 | else if (auto_window_vscroll_p) |
| 4777 | { | 4777 | { |
| @@ -4915,7 +4915,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4915 | } | 4915 | } |
| 4916 | else | 4916 | else |
| 4917 | { | 4917 | { |
| 4918 | bidi_unshelve_cache (itdata); | 4918 | bidi_unshelve_cache (itdata, 0); |
| 4919 | if (noerror) | 4919 | if (noerror) |
| 4920 | return; | 4920 | return; |
| 4921 | else if (n < 0) /* could happen with empty buffers */ | 4921 | else if (n < 0) /* could happen with empty buffers */ |
| @@ -4932,7 +4932,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 4932 | w->vscroll = 0; | 4932 | w->vscroll = 0; |
| 4933 | else | 4933 | else |
| 4934 | { | 4934 | { |
| 4935 | bidi_unshelve_cache (itdata); | 4935 | bidi_unshelve_cache (itdata, 0); |
| 4936 | if (noerror) | 4936 | if (noerror) |
| 4937 | return; | 4937 | return; |
| 4938 | else | 4938 | else |
| @@ -5081,7 +5081,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) | |||
| 5081 | SET_PT_BOTH (charpos, bytepos); | 5081 | SET_PT_BOTH (charpos, bytepos); |
| 5082 | } | 5082 | } |
| 5083 | } | 5083 | } |
| 5084 | bidi_unshelve_cache (itdata); | 5084 | bidi_unshelve_cache (itdata, 0); |
| 5085 | } | 5085 | } |
| 5086 | 5086 | ||
| 5087 | 5087 | ||
| @@ -5508,7 +5508,7 @@ displayed_window_lines (struct window *w) | |||
| 5508 | start_display (&it, w, start); | 5508 | start_display (&it, w, start); |
| 5509 | move_it_vertically (&it, height); | 5509 | move_it_vertically (&it, height); |
| 5510 | bottom_y = line_bottom_y (&it); | 5510 | bottom_y = line_bottom_y (&it); |
| 5511 | bidi_unshelve_cache (itdata); | 5511 | bidi_unshelve_cache (itdata, 0); |
| 5512 | 5512 | ||
| 5513 | /* rms: On a non-window display, | 5513 | /* rms: On a non-window display, |
| 5514 | the value of it.vpos at the bottom of the screen | 5514 | the value of it.vpos at the bottom of the screen |
| @@ -5614,7 +5614,7 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5614 | move_it_vertically_backward (&it, window_box_height (w) / 2); | 5614 | move_it_vertically_backward (&it, window_box_height (w) / 2); |
| 5615 | charpos = IT_CHARPOS (it); | 5615 | charpos = IT_CHARPOS (it); |
| 5616 | bytepos = IT_BYTEPOS (it); | 5616 | bytepos = IT_BYTEPOS (it); |
| 5617 | bidi_unshelve_cache (itdata); | 5617 | bidi_unshelve_cache (itdata, 0); |
| 5618 | } | 5618 | } |
| 5619 | else if (iarg < 0) | 5619 | else if (iarg < 0) |
| 5620 | { | 5620 | { |
| @@ -5662,7 +5662,7 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5662 | } | 5662 | } |
| 5663 | if (h <= 0) | 5663 | if (h <= 0) |
| 5664 | { | 5664 | { |
| 5665 | bidi_unshelve_cache (itdata); | 5665 | bidi_unshelve_cache (itdata, 0); |
| 5666 | return Qnil; | 5666 | return Qnil; |
| 5667 | } | 5667 | } |
| 5668 | 5668 | ||
| @@ -5685,7 +5685,7 @@ and redisplay normally--don't erase and redraw the frame. */) | |||
| 5685 | charpos = IT_CHARPOS (it); | 5685 | charpos = IT_CHARPOS (it); |
| 5686 | bytepos = IT_BYTEPOS (it); | 5686 | bytepos = IT_BYTEPOS (it); |
| 5687 | 5687 | ||
| 5688 | bidi_unshelve_cache (itdata); | 5688 | bidi_unshelve_cache (itdata, 0); |
| 5689 | } | 5689 | } |
| 5690 | else | 5690 | else |
| 5691 | { | 5691 | { |
diff --git a/src/xdisp.c b/src/xdisp.c index 5f9e80cd11e..77bd4e5ee9a 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); |
| @@ -2629,7 +2629,7 @@ init_iterator (struct it *it, struct window *w, | |||
| 2629 | it->paragraph_embedding = R2L; | 2629 | it->paragraph_embedding = R2L; |
| 2630 | else | 2630 | else |
| 2631 | it->paragraph_embedding = NEUTRAL_DIR; | 2631 | it->paragraph_embedding = NEUTRAL_DIR; |
| 2632 | bidi_unshelve_cache (NULL); | 2632 | bidi_unshelve_cache (NULL, 0); |
| 2633 | bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), | 2633 | bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), |
| 2634 | &it->bidi_it); | 2634 | &it->bidi_it); |
| 2635 | } | 2635 | } |
| @@ -5635,7 +5635,7 @@ back_to_previous_visible_line_start (struct it *it) | |||
| 5635 | pos = --IT_CHARPOS (it2); | 5635 | pos = --IT_CHARPOS (it2); |
| 5636 | --IT_BYTEPOS (it2); | 5636 | --IT_BYTEPOS (it2); |
| 5637 | it2.sp = 0; | 5637 | it2.sp = 0; |
| 5638 | bidi_unshelve_cache (NULL); | 5638 | bidi_unshelve_cache (NULL, 0); |
| 5639 | it2.string_from_display_prop_p = 0; | 5639 | it2.string_from_display_prop_p = 0; |
| 5640 | it2.from_disp_prop_p = 0; | 5640 | it2.from_disp_prop_p = 0; |
| 5641 | if (handle_display_prop (&it2) == HANDLED_RETURN | 5641 | if (handle_display_prop (&it2) == HANDLED_RETURN |
| @@ -5827,7 +5827,7 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p) | |||
| 5827 | { | 5827 | { |
| 5828 | bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), | 5828 | bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), |
| 5829 | &it->bidi_it); | 5829 | &it->bidi_it); |
| 5830 | bidi_unshelve_cache (NULL); | 5830 | bidi_unshelve_cache (NULL, 0); |
| 5831 | it->bidi_it.paragraph_dir = NEUTRAL_DIR; | 5831 | it->bidi_it.paragraph_dir = NEUTRAL_DIR; |
| 5832 | it->bidi_it.string.s = NULL; | 5832 | it->bidi_it.string.s = NULL; |
| 5833 | it->bidi_it.string.lstring = Qnil; | 5833 | it->bidi_it.string.lstring = Qnil; |
| @@ -7995,13 +7995,13 @@ move_it_in_display_line_to (struct it *it, | |||
| 7995 | positions smaller than TO_CHARPOS, return | 7995 | positions smaller than TO_CHARPOS, return |
| 7996 | MOVE_POS_MATCH_OR_ZV, like the unidirectional display | 7996 | MOVE_POS_MATCH_OR_ZV, like the unidirectional display |
| 7997 | did. */ | 7997 | did. */ |
| 7998 | if ((op & MOVE_TO_POS) != 0 | 7998 | if (it->bidi_p && (op & MOVE_TO_POS) != 0 |
| 7999 | && !saw_smaller_pos | 7999 | && !saw_smaller_pos |
| 8000 | && IT_CHARPOS (*it) > to_charpos) | 8000 | && IT_CHARPOS (*it) > to_charpos) |
| 8001 | { | 8001 | { |
| 8002 | result = MOVE_POS_MATCH_OR_ZV; | 8002 | if (IT_CHARPOS (ppos_it) < ZV) |
| 8003 | if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV) | ||
| 8004 | RESTORE_IT (it, &ppos_it, ppos_data); | 8003 | RESTORE_IT (it, &ppos_it, ppos_data); |
| 8004 | goto buffer_pos_reached; | ||
| 8005 | } | 8005 | } |
| 8006 | else | 8006 | else |
| 8007 | result = MOVE_NEWLINE_OR_CR; | 8007 | result = MOVE_NEWLINE_OR_CR; |
| @@ -8040,14 +8040,13 @@ move_it_in_display_line_to (struct it *it, | |||
| 8040 | character positions smaller than TO_CHARPOS, | 8040 | character positions smaller than TO_CHARPOS, |
| 8041 | return MOVE_POS_MATCH_OR_ZV, like the | 8041 | return MOVE_POS_MATCH_OR_ZV, like the |
| 8042 | unidirectional display did. */ | 8042 | unidirectional display did. */ |
| 8043 | || ((op & MOVE_TO_POS) != 0 | 8043 | || (it->bidi_p && (op & MOVE_TO_POS) != 0 |
| 8044 | && !saw_smaller_pos | 8044 | && !saw_smaller_pos |
| 8045 | && IT_CHARPOS (*it) > to_charpos)) | 8045 | && IT_CHARPOS (*it) > to_charpos)) |
| 8046 | { | 8046 | { |
| 8047 | result = MOVE_POS_MATCH_OR_ZV; | 8047 | if (!at_eob_p && IT_CHARPOS (ppos_it) < ZV) |
| 8048 | if (it->bidi_p && !at_eob_p && IT_CHARPOS (ppos_it) < ZV) | ||
| 8049 | RESTORE_IT (it, &ppos_it, ppos_data); | 8048 | RESTORE_IT (it, &ppos_it, ppos_data); |
| 8050 | break; | 8049 | goto buffer_pos_reached; |
| 8051 | } | 8050 | } |
| 8052 | if (ITERATOR_AT_END_OF_LINE_P (it)) | 8051 | if (ITERATOR_AT_END_OF_LINE_P (it)) |
| 8053 | { | 8052 | { |
| @@ -8055,14 +8054,13 @@ move_it_in_display_line_to (struct it *it, | |||
| 8055 | break; | 8054 | break; |
| 8056 | } | 8055 | } |
| 8057 | } | 8056 | } |
| 8058 | else if ((op & MOVE_TO_POS) != 0 | 8057 | else if (it->bidi_p && (op & MOVE_TO_POS) != 0 |
| 8059 | && !saw_smaller_pos | 8058 | && !saw_smaller_pos |
| 8060 | && IT_CHARPOS (*it) > to_charpos) | 8059 | && IT_CHARPOS (*it) > to_charpos) |
| 8061 | { | 8060 | { |
| 8062 | result = MOVE_POS_MATCH_OR_ZV; | 8061 | if (IT_CHARPOS (ppos_it) < ZV) |
| 8063 | if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV) | ||
| 8064 | RESTORE_IT (it, &ppos_it, ppos_data); | 8062 | RESTORE_IT (it, &ppos_it, ppos_data); |
| 8065 | break; | 8063 | goto buffer_pos_reached; |
| 8066 | } | 8064 | } |
| 8067 | result = MOVE_LINE_TRUNCATED; | 8065 | result = MOVE_LINE_TRUNCATED; |
| 8068 | break; | 8066 | break; |
| @@ -8082,13 +8080,13 @@ move_it_in_display_line_to (struct it *it, | |||
| 8082 | done: | 8080 | done: |
| 8083 | 8081 | ||
| 8084 | if (atpos_data) | 8082 | if (atpos_data) |
| 8085 | xfree (atpos_data); | 8083 | bidi_unshelve_cache (atpos_data, 1); |
| 8086 | if (atx_data) | 8084 | if (atx_data) |
| 8087 | xfree (atx_data); | 8085 | bidi_unshelve_cache (atx_data, 1); |
| 8088 | if (wrap_data) | 8086 | if (wrap_data) |
| 8089 | xfree (wrap_data); | 8087 | bidi_unshelve_cache (wrap_data, 1); |
| 8090 | if (ppos_data) | 8088 | if (ppos_data) |
| 8091 | xfree (ppos_data); | 8089 | bidi_unshelve_cache (ppos_data, 1); |
| 8092 | 8090 | ||
| 8093 | /* Restore the iterator settings altered at the beginning of this | 8091 | /* Restore the iterator settings altered at the beginning of this |
| 8094 | function. */ | 8092 | function. */ |
| @@ -8123,7 +8121,7 @@ move_it_in_display_line (struct it *it, | |||
| 8123 | (it, -1, prev_x, MOVE_TO_X); | 8121 | (it, -1, prev_x, MOVE_TO_X); |
| 8124 | } | 8122 | } |
| 8125 | else | 8123 | else |
| 8126 | xfree (save_data); | 8124 | bidi_unshelve_cache (save_data, 1); |
| 8127 | } | 8125 | } |
| 8128 | else | 8126 | else |
| 8129 | move_it_in_display_line_to (it, to_charpos, to_x, op); | 8127 | move_it_in_display_line_to (it, to_charpos, to_x, op); |
| @@ -8382,7 +8380,7 @@ move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos | |||
| 8382 | } | 8380 | } |
| 8383 | 8381 | ||
| 8384 | if (backup_data) | 8382 | if (backup_data) |
| 8385 | xfree (backup_data); | 8383 | bidi_unshelve_cache (backup_data, 1); |
| 8386 | 8384 | ||
| 8387 | TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached)); | 8385 | TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached)); |
| 8388 | } | 8386 | } |
| @@ -8461,7 +8459,7 @@ move_it_vertically_backward (struct it *it, int dy) | |||
| 8461 | RESTORE_IT (it, it, it2data); | 8459 | RESTORE_IT (it, it, it2data); |
| 8462 | if (nlines > 0) | 8460 | if (nlines > 0) |
| 8463 | move_it_by_lines (it, nlines); | 8461 | move_it_by_lines (it, nlines); |
| 8464 | xfree (it3data); | 8462 | bidi_unshelve_cache (it3data, 1); |
| 8465 | } | 8463 | } |
| 8466 | else | 8464 | else |
| 8467 | { | 8465 | { |
| @@ -8657,7 +8655,7 @@ move_it_by_lines (struct it *it, int dvpos) | |||
| 8657 | if (IT_CHARPOS (*it) >= start_charpos) | 8655 | if (IT_CHARPOS (*it) >= start_charpos) |
| 8658 | RESTORE_IT (it, &it2, it2data); | 8656 | RESTORE_IT (it, &it2, it2data); |
| 8659 | else | 8657 | else |
| 8660 | xfree (it2data); | 8658 | bidi_unshelve_cache (it2data, 1); |
| 8661 | } | 8659 | } |
| 8662 | else | 8660 | else |
| 8663 | RESTORE_IT (it, it, it2data); | 8661 | RESTORE_IT (it, it, it2data); |
| @@ -18764,6 +18762,9 @@ display_line (struct it *it) | |||
| 18764 | } | 18762 | } |
| 18765 | } | 18763 | } |
| 18766 | 18764 | ||
| 18765 | if (wrap_data) | ||
| 18766 | bidi_unshelve_cache (wrap_data, 1); | ||
| 18767 | |||
| 18767 | /* If line is not empty and hscrolled, maybe insert truncation glyphs | 18768 | /* If line is not empty and hscrolled, maybe insert truncation glyphs |
| 18768 | at the left window margin. */ | 18769 | at the left window margin. */ |
| 18769 | if (it->first_visible_x | 18770 | if (it->first_visible_x |