comparison src/fns.c @ 851:e7ee5f8bde58

[xemacs-hg @ 2002-05-23 11:46:08 by ben] fix for raymond toy's crash, alloca crashes, some recover-session improvements files.el: Recover-session improvements: Only show session files where some files can actually be recovered, and show in chronological order. subr.el, menubar-items.el: As promised to rms, the functionality in truncate-string-with-continuation-dots has been merged into truncate-string-to-width. Change callers in menubar-items.el. select.el: Document some of these funs better. Fix problem where we were doing own-clipboard twice. Makefile.in.in: Add alloca.o. Ensure that alloca.s doesn't compile into alloca.o, but allocax.o (not that it's currently used or anything.) EmacsFrame.c, abbrev.c, alloc.c, alloca.c, callint.c, callproc.c, config.h.in, device-msw.c, device-x.c, dired.c, doc.c, editfns.c, emacs.c, emodules.c, eval.c, event-Xt.c, event-msw.c, event-stream.c, file-coding.c, fileio.c, filelock.c, fns.c, glyphs-gtk.c, glyphs-msw.c, glyphs-x.c, gui-x.c, input-method-xlib.c, intl-win32.c, lisp.h, lread.c, menubar-gtk.c, menubar-msw.c, menubar.c, mule-wnnfns.c, nt.c, objects-msw.c, process-nt.c, realpath.c, redisplay-gtk.c, redisplay-output.c, redisplay-x.c, redisplay.c, search.c, select-msw.c, sysdep.c, syswindows.h, text.c, text.h, ui-byhand.c: Fix Raymond Toy's crash. Repeat to self: 2^21 - 1 is NOT the same as (2 << 21) - 1. Fix crashes due to excessive alloca(). replace alloca() with ALLOCA(), which calls the C alloca() [which uses xmalloc()] when the size is too big. Insert in various places calls to try to flush the C alloca() stored info if there is any. Add MALLOC_OR_ALLOCA(), for places that expect to be alloca()ing large blocks. This xmalloc()s when too large and records an unwind-protect to free -- relying on the caller to unbind_to() elsewhere in the function. Use it in concat(). Use MALLOC instead of ALLOCA in select-msw.c. xemacs.mak: Add alloca.o.
author ben
date Thu, 23 May 2002 11:46:46 +0000
parents 6728e641994e
children 2b6fa2618f76
comparison
equal deleted inserted replaced
850:f915ad7befaf 851:e7ee5f8bde58
615 Lisp_Object prev; 615 Lisp_Object prev;
616 struct merge_string_extents_struct *args_mse = 0; 616 struct merge_string_extents_struct *args_mse = 0;
617 Intbyte *string_result = 0; 617 Intbyte *string_result = 0;
618 Intbyte *string_result_ptr = 0; 618 Intbyte *string_result_ptr = 0;
619 struct gcpro gcpro1; 619 struct gcpro gcpro1;
620 int sdep = specpdl_depth ();
620 621
621 /* The modus operandi in Emacs is "caller gc-protects args". 622 /* The modus operandi in Emacs is "caller gc-protects args".
622 However, concat is called many times in Emacs on freshly 623 However, concat is called many times in Emacs on freshly
623 created stuff. So we help those callers out by protecting 624 created stuff. So we help those callers out by protecting
624 the args ourselves to save them a lot of temporary-variable 625 the args ourselves to save them a lot of temporary-variable
697 698
698 switch (target_type) 699 switch (target_type)
699 { 700 {
700 case c_cons: 701 case c_cons:
701 if (total_length == 0) 702 if (total_length == 0)
702 /* In append, if all but last arg are nil, return last arg */ 703 {
703 RETURN_UNGCPRO (last_tail); 704 unbind_to (sdep);
705 /* In append, if all but last arg are nil, return last arg */
706 RETURN_UNGCPRO (last_tail);
707 }
704 val = Fmake_list (make_int (total_length), Qnil); 708 val = Fmake_list (make_int (total_length), Qnil);
705 break; 709 break;
706 case c_vector: 710 case c_vector:
707 val = make_vector (total_length, Qnil); 711 val = make_vector (total_length, Qnil);
708 break; 712 break;
718 to the place where the substitution is called for in order 722 to the place where the substitution is called for in order
719 to find the place to change, and may have to do some 723 to find the place to change, and may have to do some
720 realloc()ing in order to make the char fit properly. 724 realloc()ing in order to make the char fit properly.
721 O(N^2) yuckage. */ 725 O(N^2) yuckage. */
722 val = Qnil; 726 val = Qnil;
723 string_result = (Intbyte *) alloca (total_length * MAX_EMCHAR_LEN); 727 string_result =
728 (Intbyte *) MALLOC_OR_ALLOCA (total_length * MAX_EMCHAR_LEN);
724 string_result_ptr = string_result; 729 string_result_ptr = string_result;
725 break; 730 break;
726 default: 731 default:
727 val = Qnil; 732 val = Qnil;
728 abort (); 733 abort ();
836 } 841 }
837 842
838 if (!NILP (prev)) 843 if (!NILP (prev))
839 XCDR (prev) = last_tail; 844 XCDR (prev) = last_tail;
840 845
846 unbind_to (sdep);
841 RETURN_UNGCPRO (val); 847 RETURN_UNGCPRO (val);
842 } 848 }
843 849
844 DEFUN ("copy-alist", Fcopy_alist, 1, 1, 0, /* 850 DEFUN ("copy-alist", Fcopy_alist, 1, 1, 0, /*
845 Return a copy of ALIST. 851 Return a copy of ALIST.
3098 `vals' array. By a stroke of luck, `vals' is exactly large 3104 `vals' array. By a stroke of luck, `vals' is exactly large
3099 enough to hold the elts left to be traversed as well as the 3105 enough to hold the elts left to be traversed as well as the
3100 results computed so far. 3106 results computed so far.
3101 3107
3102 if (vals == 0) we don't have any free space available and 3108 if (vals == 0) we don't have any free space available and
3103 don't want to eat up any more stack with alloca(). 3109 don't want to eat up any more stack with ALLOCA ().
3104 So we use EXTERNAL_LIST_LOOP_3_NO_DECLARE and GCPRO the tail. */ 3110 So we use EXTERNAL_LIST_LOOP_3_NO_DECLARE and GCPRO the tail. */
3105 3111
3106 if (vals) 3112 if (vals)
3107 { 3113 {
3108 Lisp_Object *val = vals; 3114 Lisp_Object *val = vals;
3754 } 3760 }
3755 #undef ADVANCE_INPUT 3761 #undef ADVANCE_INPUT
3756 #undef ADVANCE_INPUT_IGNORE_NONBASE64 3762 #undef ADVANCE_INPUT_IGNORE_NONBASE64
3757 #undef STORE_BYTE 3763 #undef STORE_BYTE
3758 3764
3759 static Lisp_Object
3760 free_malloced_ptr (Lisp_Object unwind_obj)
3761 {
3762 void *ptr = (void *)get_opaque_ptr (unwind_obj);
3763 xfree (ptr);
3764 free_opaque_ptr (unwind_obj);
3765 return Qnil;
3766 }
3767
3768 /* Don't use alloca for regions larger than this, lest we overflow
3769 the stack. */
3770 #define MAX_ALLOCA 65536
3771
3772 /* We need to setup proper unwinding, because there is a number of
3773 ways these functions can blow up, and we don't want to have memory
3774 leaks in those cases. */
3775 #define XMALLOC_OR_ALLOCA(ptr, len, type) do { \
3776 Elemcount XOA_len = (len); \
3777 if (XOA_len > MAX_ALLOCA) \
3778 { \
3779 ptr = xnew_array (type, XOA_len); \
3780 record_unwind_protect (free_malloced_ptr, \
3781 make_opaque_ptr ((void *)ptr)); \
3782 } \
3783 else \
3784 ptr = alloca_array (type, XOA_len); \
3785 } while (0)
3786
3787 #define XMALLOC_UNBIND(ptr, len, speccount) do { \
3788 if ((len) > MAX_ALLOCA) \
3789 unbind_to (speccount); \
3790 } while (0)
3791
3792 DEFUN ("base64-encode-region", Fbase64_encode_region, 2, 3, "r", /* 3765 DEFUN ("base64-encode-region", Fbase64_encode_region, 2, 3, "r", /*
3793 Base64-encode the region between START and END. 3766 Base64-encode the region between START and END.
3794 Return the length of the encoded text. 3767 Return the length of the encoded text.
3795 Optional third argument NO-LINE-BREAK means do not break long lines 3768 Optional third argument NO-LINE-BREAK means do not break long lines
3796 into shorter lines. 3769 into shorter lines.
3801 Bytebpos encoded_length; 3774 Bytebpos encoded_length;
3802 Charcount allength, length; 3775 Charcount allength, length;
3803 struct buffer *buf = current_buffer; 3776 struct buffer *buf = current_buffer;
3804 Charbpos begv, zv, old_pt = BUF_PT (buf); 3777 Charbpos begv, zv, old_pt = BUF_PT (buf);
3805 Lisp_Object input; 3778 Lisp_Object input;
3806 int speccount = specpdl_depth(); 3779 int speccount = specpdl_depth ();
3807 3780
3808 get_buffer_range_char (buf, start, end, &begv, &zv, 0); 3781 get_buffer_range_char (buf, start, end, &begv, &zv, 0);
3809 barf_if_buffer_read_only (buf, begv, zv); 3782 barf_if_buffer_read_only (buf, begv, zv);
3810 3783
3811 /* We need to allocate enough room for encoding the text. 3784 /* We need to allocate enough room for encoding the text.
3816 allength += allength / MIME_LINE_LENGTH + 1 + 6; 3789 allength += allength / MIME_LINE_LENGTH + 1 + 6;
3817 3790
3818 input = make_lisp_buffer_input_stream (buf, begv, zv, 0); 3791 input = make_lisp_buffer_input_stream (buf, begv, zv, 0);
3819 /* We needn't multiply allength with MAX_EMCHAR_LEN because all the 3792 /* We needn't multiply allength with MAX_EMCHAR_LEN because all the
3820 base64 characters will be single-byte. */ 3793 base64 characters will be single-byte. */
3821 XMALLOC_OR_ALLOCA (encoded, allength, Intbyte); 3794 encoded = (Intbyte *) MALLOC_OR_ALLOCA (allength);
3822 encoded_length = base64_encode_1 (XLSTREAM (input), encoded, 3795 encoded_length = base64_encode_1 (XLSTREAM (input), encoded,
3823 NILP (no_line_break)); 3796 NILP (no_line_break));
3824 if (encoded_length > allength) 3797 if (encoded_length > allength)
3825 abort (); 3798 abort ();
3826 Lstream_delete (XLSTREAM (input)); 3799 Lstream_delete (XLSTREAM (input));
3827 3800
3828 /* Now we have encoded the region, so we insert the new contents 3801 /* Now we have encoded the region, so we insert the new contents
3829 and delete the old. (Insert first in order to preserve markers.) */ 3802 and delete the old. (Insert first in order to preserve markers.) */
3830 buffer_insert_raw_string_1 (buf, begv, encoded, encoded_length, 0); 3803 buffer_insert_raw_string_1 (buf, begv, encoded, encoded_length, 0);
3831 XMALLOC_UNBIND (encoded, allength, speccount); 3804 unbind_to (speccount);
3832 buffer_delete_range (buf, begv + encoded_length, zv + encoded_length, 0); 3805 buffer_delete_range (buf, begv + encoded_length, zv + encoded_length, 0);
3833 3806
3834 /* Simulate FSF Emacs implementation of this function: if point was 3807 /* Simulate FSF Emacs implementation of this function: if point was
3835 in the region, place it at the beginning. */ 3808 in the region, place it at the beginning. */
3836 if (old_pt >= begv && old_pt < zv) 3809 if (old_pt >= begv && old_pt < zv)
3858 length = string_char_length (string); 3831 length = string_char_length (string);
3859 allength = length + length/3 + 1; 3832 allength = length + length/3 + 1;
3860 allength += allength / MIME_LINE_LENGTH + 1 + 6; 3833 allength += allength / MIME_LINE_LENGTH + 1 + 6;
3861 3834
3862 input = make_lisp_string_input_stream (string, 0, -1); 3835 input = make_lisp_string_input_stream (string, 0, -1);
3863 XMALLOC_OR_ALLOCA (encoded, allength, Intbyte); 3836 encoded = (Intbyte *) MALLOC_OR_ALLOCA (allength);
3864 encoded_length = base64_encode_1 (XLSTREAM (input), encoded, 3837 encoded_length = base64_encode_1 (XLSTREAM (input), encoded,
3865 NILP (no_line_break)); 3838 NILP (no_line_break));
3866 if (encoded_length > allength) 3839 if (encoded_length > allength)
3867 abort (); 3840 abort ();
3868 Lstream_delete (XLSTREAM (input)); 3841 Lstream_delete (XLSTREAM (input));
3869 result = make_string (encoded, encoded_length); 3842 result = make_string (encoded, encoded_length);
3870 XMALLOC_UNBIND (encoded, allength, speccount); 3843 unbind_to (speccount);
3871 return result; 3844 return result;
3872 } 3845 }
3873 3846
3874 DEFUN ("base64-decode-region", Fbase64_decode_region, 2, 2, "r", /* 3847 DEFUN ("base64-decode-region", Fbase64_decode_region, 2, 2, "r", /*
3875 Base64-decode the region between START and END. 3848 Base64-decode the region between START and END.
3892 3865
3893 length = zv - begv; 3866 length = zv - begv;
3894 3867
3895 input = make_lisp_buffer_input_stream (buf, begv, zv, 0); 3868 input = make_lisp_buffer_input_stream (buf, begv, zv, 0);
3896 /* We need to allocate enough room for decoding the text. */ 3869 /* We need to allocate enough room for decoding the text. */
3897 XMALLOC_OR_ALLOCA (decoded, length * MAX_EMCHAR_LEN, Intbyte); 3870 decoded = (Intbyte *) MALLOC_OR_ALLOCA (length * MAX_EMCHAR_LEN);
3898 decoded_length = base64_decode_1 (XLSTREAM (input), decoded, &cc_decoded_length); 3871 decoded_length = base64_decode_1 (XLSTREAM (input), decoded, &cc_decoded_length);
3899 if (decoded_length > length * MAX_EMCHAR_LEN) 3872 if (decoded_length > length * MAX_EMCHAR_LEN)
3900 abort (); 3873 abort ();
3901 Lstream_delete (XLSTREAM (input)); 3874 Lstream_delete (XLSTREAM (input));
3902 3875
3903 /* Now we have decoded the region, so we insert the new contents 3876 /* Now we have decoded the region, so we insert the new contents
3904 and delete the old. (Insert first in order to preserve markers.) */ 3877 and delete the old. (Insert first in order to preserve markers.) */
3905 BUF_SET_PT (buf, begv); 3878 BUF_SET_PT (buf, begv);
3906 buffer_insert_raw_string_1 (buf, begv, decoded, decoded_length, 0); 3879 buffer_insert_raw_string_1 (buf, begv, decoded, decoded_length, 0);
3907 XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN, speccount); 3880 unbind_to (speccount);
3908 buffer_delete_range (buf, begv + cc_decoded_length, 3881 buffer_delete_range (buf, begv + cc_decoded_length,
3909 zv + cc_decoded_length, 0); 3882 zv + cc_decoded_length, 0);
3910 3883
3911 /* Simulate FSF Emacs implementation of this function: if point was 3884 /* Simulate FSF Emacs implementation of this function: if point was
3912 in the region, place it at the beginning. */ 3885 in the region, place it at the beginning. */
3930 3903
3931 CHECK_STRING (string); 3904 CHECK_STRING (string);
3932 3905
3933 length = string_char_length (string); 3906 length = string_char_length (string);
3934 /* We need to allocate enough room for decoding the text. */ 3907 /* We need to allocate enough room for decoding the text. */
3935 XMALLOC_OR_ALLOCA (decoded, length * MAX_EMCHAR_LEN, Intbyte); 3908 decoded = (Intbyte *) MALLOC_OR_ALLOCA (length * MAX_EMCHAR_LEN);
3936 3909
3937 input = make_lisp_string_input_stream (string, 0, -1); 3910 input = make_lisp_string_input_stream (string, 0, -1);
3938 decoded_length = base64_decode_1 (XLSTREAM (input), decoded, 3911 decoded_length = base64_decode_1 (XLSTREAM (input), decoded,
3939 &cc_decoded_length); 3912 &cc_decoded_length);
3940 if (decoded_length > length * MAX_EMCHAR_LEN) 3913 if (decoded_length > length * MAX_EMCHAR_LEN)
3941 abort (); 3914 abort ();
3942 Lstream_delete (XLSTREAM (input)); 3915 Lstream_delete (XLSTREAM (input));
3943 3916
3944 result = make_string (decoded, decoded_length); 3917 result = make_string (decoded, decoded_length);
3945 XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN, speccount); 3918 unbind_to (speccount);
3946 return result; 3919 return result;
3947 } 3920 }
3948 3921
3949 Lisp_Object Qyes_or_no_p; 3922 Lisp_Object Qyes_or_no_p;
3950 3923