emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: transpose-regions


From: Chong Yidong
Subject: Re: transpose-regions
Date: Fri, 23 Mar 2007 13:34:12 -0400
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.96 (gnu/linux)

Stefan Monnier <address@hidden> writes:

> I think I see the problem: intervals are not Lisp objects and thus they are
> not detected by the conservative stack scanning (and they can't be GCPRO'd
> either).

Aha!  Yes, this is indeed the problem.

> Personally, I think the best solution is to rewrite transpose-regions in
> Lisp.  After all, it's only called from gnus/deuglify.el and from
> games/hanoi.el (and interactively as well, of course).

This is probably the long-term solution, but for Emacs 22 I think it's
not wise to change all that code.  Instead, I suggest setting
inhibit_garbage_collection around the calls to Fset_text_properties.
I have verified that this indeed solves the original bug.

*** emacs/src/editfns.c.~1.436.~        2007-03-23 13:21:29.000000000 -0400
--- emacs/src/editfns.c 2007-03-23 13:29:29.000000000 -0400
***************
*** 4118,4123 ****
--- 4118,4124 ----
    unsigned char *start1_addr, *start2_addr, *temp;
  
    INTERVAL cur_intv, tmp_interval1, tmp_interval_mid, tmp_interval2;
+   int count;
    cur_intv = BUF_INTERVALS (current_buffer);
  
    validate_region (&startr1, &endr1);
***************
*** 4224,4231 ****
--- 4225,4234 ----
  
        tmp_interval1 = copy_intervals (cur_intv, start1, len1);
        tmp_interval2 = copy_intervals (cur_intv, start2, len2);
+       count = inhibit_garbage_collection ();
        Fset_text_properties (make_number (start1), make_number (end2),
                            Qnil, Qnil);
+       unbind_to (count, Qnil);
  
        /* First region smaller than second.  */
        if (len1_byte < len2_byte)
***************
*** 4281,4290 ****
--- 4284,4295 ----
            record_change (start2, len2);
            tmp_interval1 = copy_intervals (cur_intv, start1, len1);
            tmp_interval2 = copy_intervals (cur_intv, start2, len2);
+         count = inhibit_garbage_collection ();
            Fset_text_properties (make_number (start1), make_number (end1),
                                Qnil, Qnil);
            Fset_text_properties (make_number (start2), make_number (end2),
                                Qnil, Qnil);
+         unbind_to (count, Qnil);
  
          SAFE_ALLOCA (temp, unsigned char *, len1_byte);
          start1_addr = BYTE_POS_ADDR (start1_byte);
***************
*** 4310,4317 ****
--- 4315,4324 ----
            tmp_interval1 = copy_intervals (cur_intv, start1, len1);
            tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid);
            tmp_interval2 = copy_intervals (cur_intv, start2, len2);
+         count = inhibit_garbage_collection ();
            Fset_text_properties (make_number (start1), make_number (end2),
                                Qnil, Qnil);
+         unbind_to (count, Qnil);
  
          /* holds region 2 */
          SAFE_ALLOCA (temp, unsigned char *, len2_byte);
***************
*** 4341,4349 ****
            tmp_interval1 = copy_intervals (cur_intv, start1, len1);
            tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid);
            tmp_interval2 = copy_intervals (cur_intv, start2, len2);
            Fset_text_properties (make_number (start1), make_number (end2),
                                Qnil, Qnil);
! 
          /* holds region 1 */
          SAFE_ALLOCA (temp, unsigned char *, len1_byte);
          start1_addr = BYTE_POS_ADDR (start1_byte);
--- 4348,4357 ----
            tmp_interval1 = copy_intervals (cur_intv, start1, len1);
            tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid);
            tmp_interval2 = copy_intervals (cur_intv, start2, len2);
+         count = inhibit_garbage_collection ();
            Fset_text_properties (make_number (start1), make_number (end2),
                                Qnil, Qnil);
!         unbind_to (count, Qnil);
          /* holds region 1 */
          SAFE_ALLOCA (temp, unsigned char *, len1_byte);
          start1_addr = BYTE_POS_ADDR (start1_byte);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]