diff options
Diffstat (limited to 'src/lisp.h')
| -rw-r--r-- | src/lisp.h | 501 |
1 files changed, 335 insertions, 166 deletions
diff --git a/src/lisp.h b/src/lisp.h index 67299706c6b..89f29ea268b 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -36,31 +36,15 @@ INLINE_HEADER_BEGIN | |||
| 36 | 36 | ||
| 37 | /* Define a TYPE constant ID as an externally visible name. Use like this: | 37 | /* Define a TYPE constant ID as an externally visible name. Use like this: |
| 38 | 38 | ||
| 39 | #define ID_val (some integer preprocessor expression) | ||
| 40 | #if ENUMABLE (ID_val) | ||
| 41 | DEFINE_GDB_SYMBOL_ENUM (ID) | ||
| 42 | #else | ||
| 43 | DEFINE_GDB_SYMBOL_BEGIN (TYPE, ID) | 39 | DEFINE_GDB_SYMBOL_BEGIN (TYPE, ID) |
| 44 | # define ID ID_val | 40 | # define ID (some integer preprocessor expression of type TYPE) |
| 45 | DEFINE_GDB_SYMBOL_END (ID) | 41 | DEFINE_GDB_SYMBOL_END (ID) |
| 46 | #endif | ||
| 47 | 42 | ||
| 48 | This hack is for the benefit of compilers that do not make macro | 43 | This hack is for the benefit of compilers that do not make macro |
| 49 | definitions visible to the debugger. It's used for symbols that | 44 | definitions or enums visible to the debugger. It's used for symbols |
| 50 | .gdbinit needs, symbols whose values may not fit in 'int' (where an | 45 | that .gdbinit needs. */ |
| 51 | enum would suffice). | ||
| 52 | 46 | ||
| 53 | Some GCC versions before GCC 4.2 omit enums in debugging output; | 47 | #ifdef MAIN_PROGRAM |
| 54 | see GCC bug 23336. So don't use enums with older GCC. */ | ||
| 55 | |||
| 56 | #if !defined __GNUC__ || 4 < __GNUC__ + (2 <= __GNUC_MINOR__) | ||
| 57 | # define ENUMABLE(val) (INT_MIN <= (val) && (val) <= INT_MAX) | ||
| 58 | #else | ||
| 59 | # define ENUMABLE(val) 0 | ||
| 60 | #endif | ||
| 61 | |||
| 62 | #define DEFINE_GDB_SYMBOL_ENUM(id) enum { id = id##_val }; | ||
| 63 | #if defined MAIN_PROGRAM | ||
| 64 | # define DEFINE_GDB_SYMBOL_BEGIN(type, id) type const id EXTERNALLY_VISIBLE | 48 | # define DEFINE_GDB_SYMBOL_BEGIN(type, id) type const id EXTERNALLY_VISIBLE |
| 65 | # define DEFINE_GDB_SYMBOL_END(id) = id; | 49 | # define DEFINE_GDB_SYMBOL_END(id) = id; |
| 66 | #else | 50 | #else |
| @@ -88,7 +72,8 @@ DEFINE_GDB_SYMBOL_END (GCTYPEBITS) | |||
| 88 | 2. We know malloc returns a multiple of 8. */ | 72 | 2. We know malloc returns a multiple of 8. */ |
| 89 | #if (defined alignas \ | 73 | #if (defined alignas \ |
| 90 | && (defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ \ | 74 | && (defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ \ |
| 91 | || defined DARWIN_OS || defined __sun || defined __MINGW32__)) | 75 | || defined DARWIN_OS || defined __sun || defined __MINGW32__ \ |
| 76 | || defined CYGWIN)) | ||
| 92 | # define NONPOINTER_BITS 0 | 77 | # define NONPOINTER_BITS 0 |
| 93 | #else | 78 | #else |
| 94 | # define NONPOINTER_BITS GCTYPEBITS | 79 | # define NONPOINTER_BITS GCTYPEBITS |
| @@ -297,6 +282,11 @@ error !; | |||
| 297 | # endif | 282 | # endif |
| 298 | #endif | 283 | #endif |
| 299 | 284 | ||
| 285 | #ifdef HAVE_STRUCT_ATTRIBUTE_ALIGNED | ||
| 286 | # define GCALIGNED __attribute__ ((aligned (GCALIGNMENT))) | ||
| 287 | #else | ||
| 288 | # define GCALIGNED /* empty */ | ||
| 289 | #endif | ||
| 300 | 290 | ||
| 301 | /* Some operations are so commonly executed that they are implemented | 291 | /* Some operations are so commonly executed that they are implemented |
| 302 | as macros, not functions, because otherwise runtime performance would | 292 | as macros, not functions, because otherwise runtime performance would |
| @@ -590,25 +580,15 @@ LISP_MACRO_DEFUN (XIL, Lisp_Object, (EMACS_INT i), (i)) | |||
| 590 | 580 | ||
| 591 | /* In the size word of a vector, this bit means the vector has been marked. */ | 581 | /* In the size word of a vector, this bit means the vector has been marked. */ |
| 592 | 582 | ||
| 593 | #define ARRAY_MARK_FLAG_val PTRDIFF_MIN | ||
| 594 | #if ENUMABLE (ARRAY_MARK_FLAG_val) | ||
| 595 | DEFINE_GDB_SYMBOL_ENUM (ARRAY_MARK_FLAG) | ||
| 596 | #else | ||
| 597 | DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG) | 583 | DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG) |
| 598 | # define ARRAY_MARK_FLAG ARRAY_MARK_FLAG_val | 584 | # define ARRAY_MARK_FLAG PTRDIFF_MIN |
| 599 | DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG) | 585 | DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG) |
| 600 | #endif | ||
| 601 | 586 | ||
| 602 | /* In the size word of a struct Lisp_Vector, this bit means it's really | 587 | /* In the size word of a struct Lisp_Vector, this bit means it's really |
| 603 | some other vector-like object. */ | 588 | some other vector-like object. */ |
| 604 | #define PSEUDOVECTOR_FLAG_val (PTRDIFF_MAX - PTRDIFF_MAX / 2) | ||
| 605 | #if ENUMABLE (PSEUDOVECTOR_FLAG_val) | ||
| 606 | DEFINE_GDB_SYMBOL_ENUM (PSEUDOVECTOR_FLAG) | ||
| 607 | #else | ||
| 608 | DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG) | 589 | DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG) |
| 609 | # define PSEUDOVECTOR_FLAG PSEUDOVECTOR_FLAG_val | 590 | # define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2) |
| 610 | DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG) | 591 | DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG) |
| 611 | #endif | ||
| 612 | 592 | ||
| 613 | /* In a pseudovector, the size field actually contains a word with one | 593 | /* In a pseudovector, the size field actually contains a word with one |
| 614 | PSEUDOVECTOR_FLAG bit set, and one of the following values extracted | 594 | PSEUDOVECTOR_FLAG bit set, and one of the following values extracted |
| @@ -661,14 +641,9 @@ enum More_Lisp_Bits | |||
| 661 | that cons. */ | 641 | that cons. */ |
| 662 | 642 | ||
| 663 | /* Mask for the value (as opposed to the type bits) of a Lisp object. */ | 643 | /* Mask for the value (as opposed to the type bits) of a Lisp object. */ |
| 664 | #define VALMASK_val (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX) | ||
| 665 | #if ENUMABLE (VALMASK_val) | ||
| 666 | DEFINE_GDB_SYMBOL_ENUM (VALMASK) | ||
| 667 | #else | ||
| 668 | DEFINE_GDB_SYMBOL_BEGIN (EMACS_INT, VALMASK) | 644 | DEFINE_GDB_SYMBOL_BEGIN (EMACS_INT, VALMASK) |
| 669 | # define VALMASK VALMASK_val | 645 | # define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX) |
| 670 | DEFINE_GDB_SYMBOL_END (VALMASK) | 646 | DEFINE_GDB_SYMBOL_END (VALMASK) |
| 671 | #endif | ||
| 672 | 647 | ||
| 673 | /* Largest and smallest representable fixnum values. These are the C | 648 | /* Largest and smallest representable fixnum values. These are the C |
| 674 | values. They are macros for use in static initializers. */ | 649 | values. They are macros for use in static initializers. */ |
| @@ -1015,7 +990,7 @@ LISP_MACRO_DEFUN_VOID (CHECK_TYPE, | |||
| 1015 | 990 | ||
| 1016 | typedef struct interval *INTERVAL; | 991 | typedef struct interval *INTERVAL; |
| 1017 | 992 | ||
| 1018 | struct Lisp_Cons | 993 | struct GCALIGNED Lisp_Cons |
| 1019 | { | 994 | { |
| 1020 | /* Car of this cons cell. */ | 995 | /* Car of this cons cell. */ |
| 1021 | Lisp_Object car; | 996 | Lisp_Object car; |
| @@ -1097,7 +1072,7 @@ CDR_SAFE (Lisp_Object c) | |||
| 1097 | 1072 | ||
| 1098 | /* In a string or vector, the sign bit of the `size' is the gc mark bit. */ | 1073 | /* In a string or vector, the sign bit of the `size' is the gc mark bit. */ |
| 1099 | 1074 | ||
| 1100 | struct Lisp_String | 1075 | struct GCALIGNED Lisp_String |
| 1101 | { | 1076 | { |
| 1102 | ptrdiff_t size; | 1077 | ptrdiff_t size; |
| 1103 | ptrdiff_t size_byte; | 1078 | ptrdiff_t size_byte; |
| @@ -3036,6 +3011,16 @@ struct gcpro | |||
| 3036 | ptrdiff_t nvars; | 3011 | ptrdiff_t nvars; |
| 3037 | 3012 | ||
| 3038 | #ifdef DEBUG_GCPRO | 3013 | #ifdef DEBUG_GCPRO |
| 3014 | /* File name where this record is used. */ | ||
| 3015 | const char *name; | ||
| 3016 | |||
| 3017 | /* Line number in this file. */ | ||
| 3018 | int lineno; | ||
| 3019 | |||
| 3020 | /* Index in the local chain of records. */ | ||
| 3021 | int idx; | ||
| 3022 | |||
| 3023 | /* Nesting level. */ | ||
| 3039 | int level; | 3024 | int level; |
| 3040 | #endif | 3025 | #endif |
| 3041 | }; | 3026 | }; |
| @@ -3091,122 +3076,150 @@ struct gcpro | |||
| 3091 | 3076 | ||
| 3092 | #ifndef DEBUG_GCPRO | 3077 | #ifndef DEBUG_GCPRO |
| 3093 | 3078 | ||
| 3094 | #define GCPRO1(varname) \ | 3079 | #define GCPRO1(a) \ |
| 3095 | {gcpro1.next = gcprolist; gcpro1.var = &varname; gcpro1.nvars = 1; \ | 3080 | { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ |
| 3096 | gcprolist = &gcpro1; } | 3081 | gcprolist = &gcpro1; } |
| 3097 | 3082 | ||
| 3098 | #define GCPRO2(varname1, varname2) \ | 3083 | #define GCPRO2(a, b) \ |
| 3099 | {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ | 3084 | { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ |
| 3100 | gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ | 3085 | gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ |
| 3101 | gcprolist = &gcpro2; } | 3086 | gcprolist = &gcpro2; } |
| 3087 | |||
| 3088 | #define GCPRO3(a, b, c) \ | ||
| 3089 | { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ | ||
| 3090 | gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ | ||
| 3091 | gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ | ||
| 3092 | gcprolist = &gcpro3; } | ||
| 3093 | |||
| 3094 | #define GCPRO4(a, b, c, d) \ | ||
| 3095 | { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ | ||
| 3096 | gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ | ||
| 3097 | gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ | ||
| 3098 | gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ | ||
| 3099 | gcprolist = &gcpro4; } | ||
| 3100 | |||
| 3101 | #define GCPRO5(a, b, c, d, e) \ | ||
| 3102 | { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ | ||
| 3103 | gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ | ||
| 3104 | gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ | ||
| 3105 | gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ | ||
| 3106 | gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \ | ||
| 3107 | gcprolist = &gcpro5; } | ||
| 3108 | |||
| 3109 | #define GCPRO6(a, b, c, d, e, f) \ | ||
| 3110 | { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ | ||
| 3111 | gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ | ||
| 3112 | gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ | ||
| 3113 | gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ | ||
| 3114 | gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \ | ||
| 3115 | gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \ | ||
| 3116 | gcprolist = &gcpro6; } | ||
| 3102 | 3117 | ||
| 3103 | #define GCPRO3(varname1, varname2, varname3) \ | 3118 | #define GCPRO7(a, b, c, d, e, f, g) \ |
| 3104 | {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ | 3119 | { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ |
| 3105 | gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ | 3120 | gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ |
| 3106 | gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ | 3121 | gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ |
| 3107 | gcprolist = &gcpro3; } | 3122 | gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ |
| 3108 | 3123 | gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \ | |
| 3109 | #define GCPRO4(varname1, varname2, varname3, varname4) \ | 3124 | gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \ |
| 3110 | {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ | 3125 | gcpro7.next = &gcpro6; gcpro7.var = &(g); gcpro7.nvars = 1; \ |
| 3111 | gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ | 3126 | gcprolist = &gcpro7; } |
| 3112 | gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ | ||
| 3113 | gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \ | ||
| 3114 | gcprolist = &gcpro4; } | ||
| 3115 | |||
| 3116 | #define GCPRO5(varname1, varname2, varname3, varname4, varname5) \ | ||
| 3117 | {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ | ||
| 3118 | gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ | ||
| 3119 | gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ | ||
| 3120 | gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \ | ||
| 3121 | gcpro5.next = &gcpro4; gcpro5.var = &varname5; gcpro5.nvars = 1; \ | ||
| 3122 | gcprolist = &gcpro5; } | ||
| 3123 | |||
| 3124 | #define GCPRO6(varname1, varname2, varname3, varname4, varname5, varname6) \ | ||
| 3125 | {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ | ||
| 3126 | gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ | ||
| 3127 | gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ | ||
| 3128 | gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \ | ||
| 3129 | gcpro5.next = &gcpro4; gcpro5.var = &varname5; gcpro5.nvars = 1; \ | ||
| 3130 | gcpro6.next = &gcpro5; gcpro6.var = &varname6; gcpro6.nvars = 1; \ | ||
| 3131 | gcprolist = &gcpro6; } | ||
| 3132 | |||
| 3133 | #define GCPRO7(a, b, c, d, e, f, g) \ | ||
| 3134 | {gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ | ||
| 3135 | gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ | ||
| 3136 | gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ | ||
| 3137 | gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ | ||
| 3138 | gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \ | ||
| 3139 | gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \ | ||
| 3140 | gcpro7.next = &gcpro6; gcpro7.var = &(g); gcpro7.nvars = 1; \ | ||
| 3141 | gcprolist = &gcpro7; } | ||
| 3142 | 3127 | ||
| 3143 | #define UNGCPRO (gcprolist = gcpro1.next) | 3128 | #define UNGCPRO (gcprolist = gcpro1.next) |
| 3144 | 3129 | ||
| 3145 | #else | 3130 | #else /* !DEBUG_GCPRO */ |
| 3146 | 3131 | ||
| 3147 | extern int gcpro_level; | 3132 | extern int gcpro_level; |
| 3148 | 3133 | ||
| 3149 | #define GCPRO1(varname) \ | 3134 | #define GCPRO1(a) \ |
| 3150 | {gcpro1.next = gcprolist; gcpro1.var = &varname; gcpro1.nvars = 1; \ | 3135 | { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ |
| 3151 | gcpro1.level = gcpro_level++; \ | 3136 | gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \ |
| 3152 | gcprolist = &gcpro1; } | 3137 | gcpro1.level = gcpro_level++; \ |
| 3153 | 3138 | gcprolist = &gcpro1; } | |
| 3154 | #define GCPRO2(varname1, varname2) \ | 3139 | |
| 3155 | {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ | 3140 | #define GCPRO2(a, b) \ |
| 3156 | gcpro1.level = gcpro_level; \ | 3141 | { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ |
| 3157 | gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ | 3142 | gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \ |
| 3158 | gcpro2.level = gcpro_level++; \ | 3143 | gcpro1.level = gcpro_level; \ |
| 3159 | gcprolist = &gcpro2; } | 3144 | gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ |
| 3160 | 3145 | gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \ | |
| 3161 | #define GCPRO3(varname1, varname2, varname3) \ | 3146 | gcpro2.level = gcpro_level++; \ |
| 3162 | {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ | 3147 | gcprolist = &gcpro2; } |
| 3163 | gcpro1.level = gcpro_level; \ | 3148 | |
| 3164 | gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ | 3149 | #define GCPRO3(a, b, c) \ |
| 3165 | gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ | 3150 | { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ |
| 3166 | gcpro3.level = gcpro_level++; \ | 3151 | gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \ |
| 3167 | gcprolist = &gcpro3; } | 3152 | gcpro1.level = gcpro_level; \ |
| 3168 | 3153 | gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ | |
| 3169 | #define GCPRO4(varname1, varname2, varname3, varname4) \ | 3154 | gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \ |
| 3170 | {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ | 3155 | gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ |
| 3171 | gcpro1.level = gcpro_level; \ | 3156 | gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3; \ |
| 3172 | gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ | 3157 | gcpro3.level = gcpro_level++; \ |
| 3173 | gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ | 3158 | gcprolist = &gcpro3; } |
| 3174 | gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \ | 3159 | |
| 3175 | gcpro4.level = gcpro_level++; \ | 3160 | #define GCPRO4(a, b, c, d) \ |
| 3176 | gcprolist = &gcpro4; } | 3161 | { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ |
| 3177 | 3162 | gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \ | |
| 3178 | #define GCPRO5(varname1, varname2, varname3, varname4, varname5) \ | 3163 | gcpro1.level = gcpro_level; \ |
| 3179 | {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ | 3164 | gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ |
| 3180 | gcpro1.level = gcpro_level; \ | 3165 | gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \ |
| 3181 | gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ | 3166 | gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ |
| 3182 | gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ | 3167 | gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3; \ |
| 3183 | gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \ | 3168 | gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ |
| 3184 | gcpro5.next = &gcpro4; gcpro5.var = &varname5; gcpro5.nvars = 1; \ | 3169 | gcpro4.name = __FILE__; gcpro4.lineno = __LINE__; gcpro4.idx = 4; \ |
| 3185 | gcpro5.level = gcpro_level++; \ | 3170 | gcpro4.level = gcpro_level++; \ |
| 3186 | gcprolist = &gcpro5; } | 3171 | gcprolist = &gcpro4; } |
| 3187 | 3172 | ||
| 3188 | #define GCPRO6(varname1, varname2, varname3, varname4, varname5, varname6) \ | 3173 | #define GCPRO5(a, b, c, d, e) \ |
| 3189 | {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ | 3174 | { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ |
| 3190 | gcpro1.level = gcpro_level; \ | 3175 | gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \ |
| 3191 | gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ | 3176 | gcpro1.level = gcpro_level; \ |
| 3192 | gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ | 3177 | gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ |
| 3193 | gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \ | 3178 | gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \ |
| 3194 | gcpro5.next = &gcpro4; gcpro5.var = &varname5; gcpro5.nvars = 1; \ | 3179 | gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ |
| 3195 | gcpro6.next = &gcpro5; gcpro6.var = &varname6; gcpro6.nvars = 1; \ | 3180 | gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3; \ |
| 3196 | gcpro6.level = gcpro_level++; \ | 3181 | gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ |
| 3197 | gcprolist = &gcpro6; } | 3182 | gcpro4.name = __FILE__; gcpro4.lineno = __LINE__; gcpro4.idx = 4; \ |
| 3183 | gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \ | ||
| 3184 | gcpro5.name = __FILE__; gcpro5.lineno = __LINE__; gcpro5.idx = 5; \ | ||
| 3185 | gcpro5.level = gcpro_level++; \ | ||
| 3186 | gcprolist = &gcpro5; } | ||
| 3187 | |||
| 3188 | #define GCPRO6(a, b, c, d, e, f) \ | ||
| 3189 | { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ | ||
| 3190 | gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \ | ||
| 3191 | gcpro1.level = gcpro_level; \ | ||
| 3192 | gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ | ||
| 3193 | gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \ | ||
| 3194 | gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ | ||
| 3195 | gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3; \ | ||
| 3196 | gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ | ||
| 3197 | gcpro4.name = __FILE__; gcpro4.lineno = __LINE__; gcpro4.idx = 4; \ | ||
| 3198 | gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \ | ||
| 3199 | gcpro5.name = __FILE__; gcpro5.lineno = __LINE__; gcpro5.idx = 5; \ | ||
| 3200 | gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \ | ||
| 3201 | gcpro6.name = __FILE__; gcpro6.lineno = __LINE__; gcpro6.idx = 6; \ | ||
| 3202 | gcpro6.level = gcpro_level++; \ | ||
| 3203 | gcprolist = &gcpro6; } | ||
| 3198 | 3204 | ||
| 3199 | #define GCPRO7(a, b, c, d, e, f, g) \ | 3205 | #define GCPRO7(a, b, c, d, e, f, g) \ |
| 3200 | {gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ | 3206 | { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ |
| 3201 | gcpro1.level = gcpro_level; \ | 3207 | gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \ |
| 3202 | gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ | 3208 | gcpro1.level = gcpro_level; \ |
| 3203 | gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ | 3209 | gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ |
| 3204 | gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ | 3210 | gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \ |
| 3205 | gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \ | 3211 | gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ |
| 3206 | gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \ | 3212 | gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3; \ |
| 3207 | gcpro7.next = &gcpro6; gcpro7.var = &(g); gcpro7.nvars = 1; \ | 3213 | gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ |
| 3208 | gcpro7.level = gcpro_level++; \ | 3214 | gcpro4.name = __FILE__; gcpro4.lineno = __LINE__; gcpro4.idx = 4; \ |
| 3209 | gcprolist = &gcpro7; } | 3215 | gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \ |
| 3216 | gcpro5.name = __FILE__; gcpro5.lineno = __LINE__; gcpro5.idx = 5; \ | ||
| 3217 | gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \ | ||
| 3218 | gcpro6.name = __FILE__; gcpro6.lineno = __LINE__; gcpro6.idx = 6; \ | ||
| 3219 | gcpro7.next = &gcpro6; gcpro7.var = &(g); gcpro7.nvars = 1; \ | ||
| 3220 | gcpro7.name = __FILE__; gcpro7.lineno = __LINE__; gcpro7.idx = 7; \ | ||
| 3221 | gcpro7.level = gcpro_level++; \ | ||
| 3222 | gcprolist = &gcpro7; } | ||
| 3210 | 3223 | ||
| 3211 | #define UNGCPRO \ | 3224 | #define UNGCPRO \ |
| 3212 | (--gcpro_level != gcpro1.level \ | 3225 | (--gcpro_level != gcpro1.level \ |
| @@ -3620,6 +3633,10 @@ extern void syms_of_xsettings (void); | |||
| 3620 | /* Defined in vm-limit.c. */ | 3633 | /* Defined in vm-limit.c. */ |
| 3621 | extern void memory_warnings (void *, void (*warnfun) (const char *)); | 3634 | extern void memory_warnings (void *, void (*warnfun) (const char *)); |
| 3622 | 3635 | ||
| 3636 | /* Defined in character.c. */ | ||
| 3637 | extern void parse_str_as_multibyte (const unsigned char *, ptrdiff_t, | ||
| 3638 | ptrdiff_t *, ptrdiff_t *); | ||
| 3639 | |||
| 3623 | /* Defined in alloc.c. */ | 3640 | /* Defined in alloc.c. */ |
| 3624 | extern void check_pure_size (void); | 3641 | extern void check_pure_size (void); |
| 3625 | extern void free_misc (Lisp_Object); | 3642 | extern void free_misc (Lisp_Object); |
| @@ -3629,7 +3646,7 @@ extern _Noreturn void memory_full (size_t); | |||
| 3629 | extern _Noreturn void buffer_memory_full (ptrdiff_t); | 3646 | extern _Noreturn void buffer_memory_full (ptrdiff_t); |
| 3630 | extern bool survives_gc_p (Lisp_Object); | 3647 | extern bool survives_gc_p (Lisp_Object); |
| 3631 | extern void mark_object (Lisp_Object); | 3648 | extern void mark_object (Lisp_Object); |
| 3632 | #if defined REL_ALLOC && !defined SYSTEM_MALLOC | 3649 | #if defined REL_ALLOC && !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC |
| 3633 | extern void refill_memory_reserve (void); | 3650 | extern void refill_memory_reserve (void); |
| 3634 | #endif | 3651 | #endif |
| 3635 | extern const char *pending_malloc_warning; | 3652 | extern const char *pending_malloc_warning; |
| @@ -3852,6 +3869,7 @@ extern Lisp_Object Qlexical_binding; | |||
| 3852 | extern Lisp_Object check_obarray (Lisp_Object); | 3869 | extern Lisp_Object check_obarray (Lisp_Object); |
| 3853 | extern Lisp_Object intern_1 (const char *, ptrdiff_t); | 3870 | extern Lisp_Object intern_1 (const char *, ptrdiff_t); |
| 3854 | extern Lisp_Object intern_c_string_1 (const char *, ptrdiff_t); | 3871 | extern Lisp_Object intern_c_string_1 (const char *, ptrdiff_t); |
| 3872 | extern Lisp_Object intern_driver (Lisp_Object, Lisp_Object, ptrdiff_t); | ||
| 3855 | extern Lisp_Object oblookup (Lisp_Object, const char *, ptrdiff_t, ptrdiff_t); | 3873 | extern Lisp_Object oblookup (Lisp_Object, const char *, ptrdiff_t, ptrdiff_t); |
| 3856 | INLINE void | 3874 | INLINE void |
| 3857 | LOADHIST_ATTACH (Lisp_Object x) | 3875 | LOADHIST_ATTACH (Lisp_Object x) |
| @@ -3882,6 +3900,7 @@ intern_c_string (const char *str) | |||
| 3882 | } | 3900 | } |
| 3883 | 3901 | ||
| 3884 | /* Defined in eval.c. */ | 3902 | /* Defined in eval.c. */ |
| 3903 | extern EMACS_INT lisp_eval_depth; | ||
| 3885 | extern Lisp_Object Qexit, Qinteractive, Qcommandp, Qmacro; | 3904 | extern Lisp_Object Qexit, Qinteractive, Qcommandp, Qmacro; |
| 3886 | extern Lisp_Object Qinhibit_quit, Qinternal_interpreter_environment, Qclosure; | 3905 | extern Lisp_Object Qinhibit_quit, Qinternal_interpreter_environment, Qclosure; |
| 3887 | extern Lisp_Object Qand_rest; | 3906 | extern Lisp_Object Qand_rest; |
| @@ -3949,8 +3968,7 @@ extern Lisp_Object safe_call2 (Lisp_Object, Lisp_Object, Lisp_Object); | |||
| 3949 | extern void init_eval (void); | 3968 | extern void init_eval (void); |
| 3950 | extern void syms_of_eval (void); | 3969 | extern void syms_of_eval (void); |
| 3951 | extern void unwind_body (Lisp_Object); | 3970 | extern void unwind_body (Lisp_Object); |
| 3952 | extern void record_in_backtrace (Lisp_Object function, | 3971 | extern ptrdiff_t record_in_backtrace (Lisp_Object, Lisp_Object *, ptrdiff_t); |
| 3953 | Lisp_Object *args, ptrdiff_t nargs); | ||
| 3954 | extern void mark_specpdl (void); | 3972 | extern void mark_specpdl (void); |
| 3955 | extern void get_backtrace (Lisp_Object array); | 3973 | extern void get_backtrace (Lisp_Object array); |
| 3956 | Lisp_Object backtrace_top_function (void); | 3974 | Lisp_Object backtrace_top_function (void); |
| @@ -3972,7 +3990,6 @@ extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, | |||
| 3972 | ptrdiff_t, bool); | 3990 | ptrdiff_t, bool); |
| 3973 | extern void init_editfns (void); | 3991 | extern void init_editfns (void); |
| 3974 | extern void syms_of_editfns (void); | 3992 | extern void syms_of_editfns (void); |
| 3975 | extern void set_time_zone_rule (const char *); | ||
| 3976 | 3993 | ||
| 3977 | /* Defined in buffer.c. */ | 3994 | /* Defined in buffer.c. */ |
| 3978 | extern bool mouse_face_overlay_overlaps (Lisp_Object); | 3995 | extern bool mouse_face_overlay_overlaps (Lisp_Object); |
| @@ -4025,7 +4042,7 @@ extern _Noreturn void report_file_error (const char *, Lisp_Object); | |||
| 4025 | extern bool internal_delete_file (Lisp_Object); | 4042 | extern bool internal_delete_file (Lisp_Object); |
| 4026 | extern Lisp_Object emacs_readlinkat (int, const char *); | 4043 | extern Lisp_Object emacs_readlinkat (int, const char *); |
| 4027 | extern bool file_directory_p (const char *); | 4044 | extern bool file_directory_p (const char *); |
| 4028 | extern bool file_accessible_directory_p (const char *); | 4045 | extern bool file_accessible_directory_p (Lisp_Object); |
| 4029 | extern void init_fileio (void); | 4046 | extern void init_fileio (void); |
| 4030 | extern void syms_of_fileio (void); | 4047 | extern void syms_of_fileio (void); |
| 4031 | extern Lisp_Object make_temp_name (Lisp_Object, bool); | 4048 | extern Lisp_Object make_temp_name (Lisp_Object, bool); |
| @@ -4093,6 +4110,9 @@ extern Lisp_Object Qdisabled, QCfilter; | |||
| 4093 | extern Lisp_Object Qup, Qdown; | 4110 | extern Lisp_Object Qup, Qdown; |
| 4094 | extern Lisp_Object last_undo_boundary; | 4111 | extern Lisp_Object last_undo_boundary; |
| 4095 | extern bool input_pending; | 4112 | extern bool input_pending; |
| 4113 | #ifdef HAVE_STACK_OVERFLOW_HANDLING | ||
| 4114 | extern sigjmp_buf return_to_command_loop; | ||
| 4115 | #endif | ||
| 4096 | extern Lisp_Object menu_bar_items (Lisp_Object); | 4116 | extern Lisp_Object menu_bar_items (Lisp_Object); |
| 4097 | extern Lisp_Object tool_bar_items (Lisp_Object, int *); | 4117 | extern Lisp_Object tool_bar_items (Lisp_Object, int *); |
| 4098 | extern void discard_mouse_events (void); | 4118 | extern void discard_mouse_events (void); |
| @@ -4295,6 +4315,7 @@ extern void lock_file (Lisp_Object); | |||
| 4295 | extern void unlock_file (Lisp_Object); | 4315 | extern void unlock_file (Lisp_Object); |
| 4296 | extern void unlock_buffer (struct buffer *); | 4316 | extern void unlock_buffer (struct buffer *); |
| 4297 | extern void syms_of_filelock (void); | 4317 | extern void syms_of_filelock (void); |
| 4318 | extern int str_collate (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); | ||
| 4298 | 4319 | ||
| 4299 | /* Defined in sound.c. */ | 4320 | /* Defined in sound.c. */ |
| 4300 | extern void syms_of_sound (void); | 4321 | extern void syms_of_sound (void); |
| @@ -4376,6 +4397,7 @@ extern void syms_of_xsmfns (void); | |||
| 4376 | extern void syms_of_xselect (void); | 4397 | extern void syms_of_xselect (void); |
| 4377 | 4398 | ||
| 4378 | /* Defined in xterm.c. */ | 4399 | /* Defined in xterm.c. */ |
| 4400 | extern void init_xterm (void); | ||
| 4379 | extern void syms_of_xterm (void); | 4401 | extern void syms_of_xterm (void); |
| 4380 | #endif /* HAVE_X_WINDOWS */ | 4402 | #endif /* HAVE_X_WINDOWS */ |
| 4381 | 4403 | ||
| @@ -4397,6 +4419,7 @@ extern void syms_of_decompress (void); | |||
| 4397 | 4419 | ||
| 4398 | #ifdef HAVE_DBUS | 4420 | #ifdef HAVE_DBUS |
| 4399 | /* Defined in dbusbind.c. */ | 4421 | /* Defined in dbusbind.c. */ |
| 4422 | void init_dbusbind (void); | ||
| 4400 | void syms_of_dbusbind (void); | 4423 | void syms_of_dbusbind (void); |
| 4401 | #endif | 4424 | #endif |
| 4402 | 4425 | ||
| @@ -4412,6 +4435,11 @@ extern void syms_of_profiler (void); | |||
| 4412 | extern char *emacs_root_dir (void); | 4435 | extern char *emacs_root_dir (void); |
| 4413 | #endif /* DOS_NT */ | 4436 | #endif /* DOS_NT */ |
| 4414 | 4437 | ||
| 4438 | /* Defined in lastfile.c. */ | ||
| 4439 | extern char my_edata[]; | ||
| 4440 | extern char my_endbss[]; | ||
| 4441 | extern char *my_endbss_static; | ||
| 4442 | |||
| 4415 | /* True means ^G can quit instantly. */ | 4443 | /* True means ^G can quit instantly. */ |
| 4416 | extern bool immediate_quit; | 4444 | extern bool immediate_quit; |
| 4417 | 4445 | ||
| @@ -4427,15 +4455,28 @@ extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t); | |||
| 4427 | extern char *xstrdup (const char *) ATTRIBUTE_MALLOC; | 4455 | extern char *xstrdup (const char *) ATTRIBUTE_MALLOC; |
| 4428 | extern char *xlispstrdup (Lisp_Object) ATTRIBUTE_MALLOC; | 4456 | extern char *xlispstrdup (Lisp_Object) ATTRIBUTE_MALLOC; |
| 4429 | extern void dupstring (char **, char const *); | 4457 | extern void dupstring (char **, char const *); |
| 4430 | extern void xputenv (const char *); | ||
| 4431 | 4458 | ||
| 4432 | extern char *egetenv (const char *); | 4459 | /* Make DEST a copy of STRING's data. Return a pointer to DEST's terminating |
| 4460 | null byte. This is like stpcpy, except the source is a Lisp string. */ | ||
| 4461 | |||
| 4462 | INLINE char * | ||
| 4463 | lispstpcpy (char *dest, Lisp_Object string) | ||
| 4464 | { | ||
| 4465 | ptrdiff_t len = SBYTES (string); | ||
| 4466 | memcpy (dest, SDATA (string), len + 1); | ||
| 4467 | return dest + len; | ||
| 4468 | } | ||
| 4469 | |||
| 4470 | extern void xputenv (const char *); | ||
| 4433 | 4471 | ||
| 4434 | /* Copy Lisp string to temporary (allocated on stack) C string. */ | 4472 | extern char *egetenv_internal (const char *, ptrdiff_t); |
| 4435 | 4473 | ||
| 4436 | #define xlispstrdupa(string) \ | 4474 | INLINE char * |
| 4437 | memcpy (alloca (SBYTES (string) + 1), \ | 4475 | egetenv (const char *var) |
| 4438 | SSDATA (string), SBYTES (string) + 1) | 4476 | { |
| 4477 | /* When VAR is a string literal, strlen can be optimized away. */ | ||
| 4478 | return egetenv_internal (var, strlen (var)); | ||
| 4479 | } | ||
| 4439 | 4480 | ||
| 4440 | /* Set up the name of the machine we're running on. */ | 4481 | /* Set up the name of the machine we're running on. */ |
| 4441 | extern void init_system_name (void); | 4482 | extern void init_system_name (void); |
| @@ -4460,12 +4501,15 @@ enum MAX_ALLOCA { MAX_ALLOCA = 16 * 1024 }; | |||
| 4460 | extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); | 4501 | extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); |
| 4461 | 4502 | ||
| 4462 | #define USE_SAFE_ALLOCA \ | 4503 | #define USE_SAFE_ALLOCA \ |
| 4504 | ptrdiff_t sa_avail = MAX_ALLOCA; \ | ||
| 4463 | ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false | 4505 | ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false |
| 4464 | 4506 | ||
| 4507 | #define AVAIL_ALLOCA(size) (sa_avail -= (size), alloca (size)) | ||
| 4508 | |||
| 4465 | /* SAFE_ALLOCA allocates a simple buffer. */ | 4509 | /* SAFE_ALLOCA allocates a simple buffer. */ |
| 4466 | 4510 | ||
| 4467 | #define SAFE_ALLOCA(size) ((size) < MAX_ALLOCA \ | 4511 | #define SAFE_ALLOCA(size) ((size) <= sa_avail \ |
| 4468 | ? alloca (size) \ | 4512 | ? AVAIL_ALLOCA (size) \ |
| 4469 | : (sa_must_free = true, record_xmalloc (size))) | 4513 | : (sa_must_free = true, record_xmalloc (size))) |
| 4470 | 4514 | ||
| 4471 | /* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER * | 4515 | /* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER * |
| @@ -4474,8 +4518,8 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); | |||
| 4474 | 4518 | ||
| 4475 | #define SAFE_NALLOCA(buf, multiplier, nitems) \ | 4519 | #define SAFE_NALLOCA(buf, multiplier, nitems) \ |
| 4476 | do { \ | 4520 | do { \ |
| 4477 | if ((nitems) <= MAX_ALLOCA / sizeof *(buf) / (multiplier)) \ | 4521 | if ((nitems) <= sa_avail / sizeof *(buf) / (multiplier)) \ |
| 4478 | (buf) = alloca (sizeof *(buf) * (multiplier) * (nitems)); \ | 4522 | (buf) = AVAIL_ALLOCA (sizeof *(buf) * (multiplier) * (nitems)); \ |
| 4479 | else \ | 4523 | else \ |
| 4480 | { \ | 4524 | { \ |
| 4481 | (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \ | 4525 | (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \ |
| @@ -4484,6 +4528,14 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); | |||
| 4484 | } \ | 4528 | } \ |
| 4485 | } while (false) | 4529 | } while (false) |
| 4486 | 4530 | ||
| 4531 | /* SAFE_ALLOCA_STRING allocates a C copy of a Lisp string. */ | ||
| 4532 | |||
| 4533 | #define SAFE_ALLOCA_STRING(ptr, string) \ | ||
| 4534 | do { \ | ||
| 4535 | (ptr) = SAFE_ALLOCA (SBYTES (string) + 1); \ | ||
| 4536 | memcpy (ptr, SDATA (string), SBYTES (string) + 1); \ | ||
| 4537 | } while (false) | ||
| 4538 | |||
| 4487 | /* SAFE_FREE frees xmalloced memory and enables GC as needed. */ | 4539 | /* SAFE_FREE frees xmalloced memory and enables GC as needed. */ |
| 4488 | 4540 | ||
| 4489 | #define SAFE_FREE() \ | 4541 | #define SAFE_FREE() \ |
| @@ -4495,13 +4547,29 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); | |||
| 4495 | } while (false) | 4547 | } while (false) |
| 4496 | 4548 | ||
| 4497 | 4549 | ||
| 4550 | /* Return floor (NBYTES / WORD_SIZE). */ | ||
| 4551 | |||
| 4552 | INLINE ptrdiff_t | ||
| 4553 | lisp_word_count (ptrdiff_t nbytes) | ||
| 4554 | { | ||
| 4555 | if (-1 >> 1 == -1) | ||
| 4556 | switch (word_size) | ||
| 4557 | { | ||
| 4558 | case 2: return nbytes >> 1; | ||
| 4559 | case 4: return nbytes >> 2; | ||
| 4560 | case 8: return nbytes >> 3; | ||
| 4561 | case 16: return nbytes >> 4; | ||
| 4562 | } | ||
| 4563 | return nbytes / word_size - (nbytes % word_size < 0); | ||
| 4564 | } | ||
| 4565 | |||
| 4498 | /* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects. */ | 4566 | /* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects. */ |
| 4499 | 4567 | ||
| 4500 | #define SAFE_ALLOCA_LISP(buf, nelt) \ | 4568 | #define SAFE_ALLOCA_LISP(buf, nelt) \ |
| 4501 | do { \ | 4569 | do { \ |
| 4502 | if ((nelt) < MAX_ALLOCA / word_size) \ | 4570 | if ((nelt) <= lisp_word_count (sa_avail)) \ |
| 4503 | (buf) = alloca ((nelt) * word_size); \ | 4571 | (buf) = AVAIL_ALLOCA ((nelt) * word_size); \ |
| 4504 | else if ((nelt) < min (PTRDIFF_MAX, SIZE_MAX) / word_size) \ | 4572 | else if ((nelt) <= min (PTRDIFF_MAX, SIZE_MAX) / word_size) \ |
| 4505 | { \ | 4573 | { \ |
| 4506 | Lisp_Object arg_; \ | 4574 | Lisp_Object arg_; \ |
| 4507 | (buf) = xmalloc ((nelt) * word_size); \ | 4575 | (buf) = xmalloc ((nelt) * word_size); \ |
| @@ -4513,6 +4581,107 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); | |||
| 4513 | memory_full (SIZE_MAX); \ | 4581 | memory_full (SIZE_MAX); \ |
| 4514 | } while (false) | 4582 | } while (false) |
| 4515 | 4583 | ||
| 4584 | |||
| 4585 | /* If USE_STACK_LISP_OBJECTS, define macros that and functions that allocate | ||
| 4586 | block-scoped conses and strings. These objects are not | ||
| 4587 | managed by the garbage collector, so they are dangerous: passing them | ||
| 4588 | out of their scope (e.g., to user code) results in undefined behavior. | ||
| 4589 | Conversely, they have better performance because GC is not involved. | ||
| 4590 | |||
| 4591 | This feature is experimental and requires careful debugging. | ||
| 4592 | Build with CPPFLAGS='-DUSE_STACK_LISP_OBJECTS=0' to disable it. */ | ||
| 4593 | |||
| 4594 | #ifndef USE_STACK_LISP_OBJECTS | ||
| 4595 | # define USE_STACK_LISP_OBJECTS true | ||
| 4596 | #endif | ||
| 4597 | |||
| 4598 | /* USE_STACK_LISP_OBJECTS requires GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS. */ | ||
| 4599 | |||
| 4600 | #if GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS | ||
| 4601 | # undef USE_STACK_LISP_OBJECTS | ||
| 4602 | # define USE_STACK_LISP_OBJECTS false | ||
| 4603 | #endif | ||
| 4604 | |||
| 4605 | /* Struct inside unions that are typically no larger and aligned enough. */ | ||
| 4606 | |||
| 4607 | union Aligned_Cons | ||
| 4608 | { | ||
| 4609 | struct Lisp_Cons s; | ||
| 4610 | double d; intmax_t i; void *p; | ||
| 4611 | }; | ||
| 4612 | |||
| 4613 | union Aligned_String | ||
| 4614 | { | ||
| 4615 | struct Lisp_String s; | ||
| 4616 | double d; intmax_t i; void *p; | ||
| 4617 | }; | ||
| 4618 | |||
| 4619 | /* True for stack-based cons and string implementations, respectively. | ||
| 4620 | Use stack-based strings only if stack-based cons also works. | ||
| 4621 | Otherwise, STACK_CONS would create heap-based cons cells that | ||
| 4622 | could point to stack-based strings, which is a no-no. */ | ||
| 4623 | |||
| 4624 | enum | ||
| 4625 | { | ||
| 4626 | USE_STACK_CONS = (USE_STACK_LISP_OBJECTS | ||
| 4627 | && alignof (union Aligned_Cons) % GCALIGNMENT == 0), | ||
| 4628 | USE_STACK_STRING = (USE_STACK_CONS | ||
| 4629 | && alignof (union Aligned_String) % GCALIGNMENT == 0) | ||
| 4630 | }; | ||
| 4631 | |||
| 4632 | /* Auxiliary macros used for auto allocation of Lisp objects. Please | ||
| 4633 | use these only in macros like AUTO_CONS that declare a local | ||
| 4634 | variable whose lifetime will be clear to the programmer. */ | ||
| 4635 | #define STACK_CONS(a, b) \ | ||
| 4636 | make_lisp_ptr (&(union Aligned_Cons) { { a, { b } } }.s, Lisp_Cons) | ||
| 4637 | #define AUTO_CONS_EXPR(a, b) \ | ||
| 4638 | (USE_STACK_CONS ? STACK_CONS (a, b) : Fcons (a, b)) | ||
| 4639 | |||
| 4640 | /* Declare NAME as an auto Lisp cons or short list if possible, a | ||
| 4641 | GC-based one otherwise. This is in the sense of the C keyword | ||
| 4642 | 'auto'; i.e., the object has the lifetime of the containing block. | ||
| 4643 | The resulting object should not be made visible to user Lisp code. */ | ||
| 4644 | |||
| 4645 | #define AUTO_CONS(name, a, b) Lisp_Object name = AUTO_CONS_EXPR (a, b) | ||
| 4646 | #define AUTO_LIST1(name, a) \ | ||
| 4647 | Lisp_Object name = (USE_STACK_CONS ? STACK_CONS (a, Qnil) : list1 (a)) | ||
| 4648 | #define AUTO_LIST2(name, a, b) \ | ||
| 4649 | Lisp_Object name = (USE_STACK_CONS \ | ||
| 4650 | ? STACK_CONS (a, STACK_CONS (b, Qnil)) \ | ||
| 4651 | : list2 (a, b)) | ||
| 4652 | #define AUTO_LIST3(name, a, b, c) \ | ||
| 4653 | Lisp_Object name = (USE_STACK_CONS \ | ||
| 4654 | ? STACK_CONS (a, STACK_CONS (b, STACK_CONS (c, Qnil))) \ | ||
| 4655 | : list3 (a, b, c)) | ||
| 4656 | #define AUTO_LIST4(name, a, b, c, d) \ | ||
| 4657 | Lisp_Object name \ | ||
| 4658 | = (USE_STACK_CONS \ | ||
| 4659 | ? STACK_CONS (a, STACK_CONS (b, STACK_CONS (c, \ | ||
| 4660 | STACK_CONS (d, Qnil)))) \ | ||
| 4661 | : list4 (a, b, c, d)) | ||
| 4662 | |||
| 4663 | /* Check whether stack-allocated strings are ASCII-only. */ | ||
| 4664 | |||
| 4665 | #if defined (ENABLE_CHECKING) && USE_STACK_LISP_OBJECTS | ||
| 4666 | extern const char *verify_ascii (const char *); | ||
| 4667 | #else | ||
| 4668 | # define verify_ascii(str) (str) | ||
| 4669 | #endif | ||
| 4670 | |||
| 4671 | /* Declare NAME as an auto Lisp string if possible, a GC-based one if not. | ||
| 4672 | Take its value from STR. STR is not necessarily copied and should | ||
| 4673 | contain only ASCII characters. The resulting Lisp string should | ||
| 4674 | not be modified or made visible to user code. */ | ||
| 4675 | |||
| 4676 | #define AUTO_STRING(name, str) \ | ||
| 4677 | Lisp_Object name = \ | ||
| 4678 | (USE_STACK_STRING \ | ||
| 4679 | ? (make_lisp_ptr \ | ||
| 4680 | ((&(union Aligned_String) \ | ||
| 4681 | {{strlen (str), -1, 0, (unsigned char *) verify_ascii (str)}}.s), \ | ||
| 4682 | Lisp_String)) \ | ||
| 4683 | : build_string (verify_ascii (str))) | ||
| 4684 | |||
| 4516 | /* Loop over all tails of a list, checking for cycles. | 4685 | /* Loop over all tails of a list, checking for cycles. |
| 4517 | FIXME: Make tortoise and n internal declarations. | 4686 | FIXME: Make tortoise and n internal declarations. |
| 4518 | FIXME: Unroll the loop body so we don't need `n'. */ | 4687 | FIXME: Unroll the loop body so we don't need `n'. */ |