all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* [PATCH 01/10] move some globals into a thread object
@ 2012-08-09 19:37 Tom Tromey
  2012-08-10  1:18 ` Stefan Monnier
  0 siblings, 1 reply; 3+ messages in thread
From: Tom Tromey @ 2012-08-09 19:37 UTC (permalink / raw
  To: Emacs discussions

This introduces a thread-state object and moves various C globals
there.  It also introduces #defines for these globals to avoid a
monster patch.

The #defines mean that this patch also has to rename a few fields
whose names clash with the defines.

There is currently just a single "thread"; so this patch does not
impact Emacs behavior in any significant way.
---
 src/Makefile.in |    2 +-
 src/alloc.c     |   12 +----
 src/buffer.c    |    2 -
 src/buffer.h    |    4 --
 src/bytecode.c  |    2 +-
 src/emacs.c     |   15 +-----
 src/eval.c      |   54 +++++++++++-----------
 src/lisp.h      |   23 +--------
 src/regex.c     |   10 ++--
 src/regex.h     |    4 +-
 src/search.c    |   22 ++++----
 src/thread.c    |   26 ++++++++++
 src/thread.h    |  140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/window.c    |    8 ++--
 14 files changed, 223 insertions(+), 101 deletions(-)
 create mode 100644 src/thread.c
 create mode 100644 src/thread.h

diff --git a/src/Makefile.in b/src/Makefile.in
index 687b3ce..c5f36c0 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -336,7 +336,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
 	eval.o floatfns.o fns.o font.o print.o lread.o \
 	syntax.o $(UNEXEC_OBJ) bytecode.o \
 	process.o gnutls.o callproc.o \
-	region-cache.o sound.o atimer.o \
+	region-cache.o sound.o atimer.o thread.o \
 	doprnt.o intervals.o textprop.o composite.o xml.o \
 	$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ)
 obj = $(base_obj) $(NS_OBJC_OBJ)
diff --git a/src/alloc.c b/src/alloc.c
index e84be98..0fdf7da 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -364,10 +364,6 @@ struct mem_node
   enum mem_type type;
 };
 
-/* Base address of stack.  Set in main.  */
-
-Lisp_Object *stack_base;
-
 /* Root of the tree describing allocated Lisp memory.  */
 
 static struct mem_node *mem_root;
@@ -415,10 +411,6 @@ static void check_gcpros (void);
 # define DEADP(x) 0
 #endif
 
-/* Recording what needs to be marked for gc.  */
-
-struct gcpro *gcprolist;
-
 /* Addresses of staticpro'd variables.  Initialize it to a nonzero
    value; otherwise some compilers put it into BSS.  */
 
@@ -4883,7 +4875,7 @@ mark_stack (void)
     Lisp_Object o;
     jmp_buf j;
   } j;
-  volatile int stack_grows_down_p = (char *) &j > (char *) stack_base;
+  volatile int stack_grows_down_p = (char *) &j > (char *) stack_bottom;
 #endif
   /* This trick flushes the register windows so that all the state of
      the process is contained in the stack.  */
@@ -4925,7 +4917,7 @@ mark_stack (void)
   /* This assumes that the stack is a contiguous region in memory.  If
      that's not the case, something has to be done here to iterate
      over the stack segments.  */
-  mark_memory (stack_base, end);
+  mark_memory (stack_bottom, end);
 
   /* Allow for marking a secondary stack, like the register stack on the
      ia64.  */
diff --git a/src/buffer.c b/src/buffer.c
index 6b68f34..33f8527 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -44,8 +44,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "keymap.h"
 #include "frame.h"
 
-struct buffer *current_buffer;		/* the current buffer */
-
 /* First buffer in chain of all buffers (in reverse order of creation).
    Threaded through ->header.next.buffer.  */
 
diff --git a/src/buffer.h b/src/buffer.h
index a52ca71..6840def 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -871,10 +871,6 @@ extern struct buffer *all_buffers;
 #define FOR_EACH_BUFFER(b) \
   for ((b) = all_buffers; (b); (b) = (b)->header.next.buffer)
 
-/* This points to the current buffer.  */
-
-extern struct buffer *current_buffer;
-
 /* This structure holds the default values of the buffer-local variables
    that have special slots in each buffer.
    The default value occupies the same slot in this structure
diff --git a/src/bytecode.c b/src/bytecode.c
index 5ac8b4f..0194594 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -328,7 +328,7 @@ struct byte_stack
    done.  Signaling an error truncates the list analogous to
    gcprolist.  */
 
-struct byte_stack *byte_stack_list;
+/* struct byte_stack *byte_stack_list; */
 
 \f
 /* Mark objects on byte_stack_list.  Called during GC.  */
diff --git a/src/emacs.c b/src/emacs.c
index 8d458c6..e1acd36 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -140,10 +140,6 @@ int running_asynch_code;
 int display_arg;
 #endif
 
-/* An address near the bottom of the stack.
-   Tells GC how to save a copy of the stack.  */
-char *stack_bottom;
-
 #if defined (DOUG_LEA_MALLOC) || defined (GNU_LINUX)
 /* The address where the heap starts (from the first sbrk (0) call).  */
 static void *my_heap_start;
@@ -687,9 +683,6 @@ void (*__malloc_initialize_hook) (void) EXTERNALLY_VISIBLE = malloc_initialize_h
 int
 main (int argc, char **argv)
 {
-#if GC_MARK_STACK
-  Lisp_Object dummy;
-#endif
   char stack_bottom_variable;
   int do_initial_setlocale;
   int skip_args = 0;
@@ -704,9 +697,8 @@ main (int argc, char **argv)
 #endif
   char *ch_to_dir;
 
-#if GC_MARK_STACK
-  stack_base = &dummy;
-#endif
+  /* Record (approximately) where the stack begins.  */
+  stack_bottom = &stack_bottom_variable;
 
 #if defined (USE_GTK) && defined (G_SLICE_ALWAYS_MALLOC)
   /* This is used by the Cygwin build.  */
@@ -852,9 +844,6 @@ main (int argc, char **argv)
     }
 #endif /* HAVE_SETRLIMIT and RLIMIT_STACK */
 
-  /* Record (approximately) where the stack begins.  */
-  stack_bottom = &stack_bottom_variable;
-
   clearerr (stdin);
 
 #ifndef SYSTEM_MALLOC
diff --git a/src/eval.c b/src/eval.c
index b531f79..768cdc1 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -42,12 +42,12 @@ struct backtrace
   unsigned int debug_on_exit : 1;
 };
 
-static struct backtrace *backtrace_list;
+/* static struct backtrace *backtrace_list; */
 
-#if !BYTE_MARK_STACK
-static
-#endif
-struct catchtag *catchlist;
+/* #if !BYTE_MARK_STACK */
+/* static */
+/* #endif */
+/* struct catchtag *catchlist; */
 
 /* Chain of condition handlers currently in effect.
    The elements of this chain are contained in the stack frames
@@ -55,10 +55,10 @@ struct catchtag *catchlist;
    When an error is signaled (by calling Fsignal, below),
    this chain is searched for an element that applies.  */
 
-#if !BYTE_MARK_STACK
-static
-#endif
-struct handler *handlerlist;
+/* #if !BYTE_MARK_STACK */
+/* static */
+/* #endif */
+/* struct handler *handlerlist; */
 
 #ifdef DEBUG_GCPRO
 /* Count levels of GCPRO to detect failure to UNGCPRO.  */
@@ -90,19 +90,19 @@ Lisp_Object Vautoload_queue;
 
 /* Current number of specbindings allocated in specpdl.  */
 
-ptrdiff_t specpdl_size;
+/* ptrdiff_t specpdl_size; */
 
 /* Pointer to beginning of specpdl.  */
 
-struct specbinding *specpdl;
+/* struct specbinding *specpdl; */
 
 /* Pointer to first unused element in specpdl.  */
 
-struct specbinding *specpdl_ptr;
+/* struct specbinding *specpdl_ptr; */
 
 /* Depth in Lisp evaluations and function calls.  */
 
-static EMACS_INT lisp_eval_depth;
+/* static EMACS_INT lisp_eval_depth; */
 
 /* The value of num_nonmacro_input_events as of the last time we
    started to enter the debugger.  If we decide to enter the debugger
@@ -1051,8 +1051,8 @@ internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object
   c.tag = tag;
   c.val = Qnil;
   c.backlist = backtrace_list;
-  c.handlerlist = handlerlist;
-  c.lisp_eval_depth = lisp_eval_depth;
+  c.f_handlerlist = handlerlist;
+  c.f_lisp_eval_depth = lisp_eval_depth;
   c.pdlcount = SPECPDL_INDEX ();
   c.poll_suppress_count = poll_suppress_count;
   c.interrupt_input_blocked = interrupt_input_blocked;
@@ -1106,7 +1106,7 @@ unwind_to_catch (struct catchtag *catch, Lisp_Object value)
       /* Unwind the specpdl stack, and then restore the proper set of
 	 handlers.  */
       unbind_to (catchlist->pdlcount, Qnil);
-      handlerlist = catchlist->handlerlist;
+      handlerlist = catchlist->f_handlerlist;
       catchlist = catchlist->next;
     }
   while (! last_time);
@@ -1127,7 +1127,7 @@ unwind_to_catch (struct catchtag *catch, Lisp_Object value)
   gcpro_level = gcprolist ? gcprolist->level + 1 : 0;
 #endif
   backtrace_list = catch->backlist;
-  lisp_eval_depth = catch->lisp_eval_depth;
+  lisp_eval_depth = catch->f_lisp_eval_depth;
 
   _longjmp (catch->jmp, 1);
 }
@@ -1231,8 +1231,8 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform,
   c.tag = Qnil;
   c.val = Qnil;
   c.backlist = backtrace_list;
-  c.handlerlist = handlerlist;
-  c.lisp_eval_depth = lisp_eval_depth;
+  c.f_handlerlist = handlerlist;
+  c.f_lisp_eval_depth = lisp_eval_depth;
   c.pdlcount = SPECPDL_INDEX ();
   c.poll_suppress_count = poll_suppress_count;
   c.interrupt_input_blocked = interrupt_input_blocked;
@@ -1286,8 +1286,8 @@ internal_condition_case (Lisp_Object (*bfun) (void), Lisp_Object handlers,
   c.tag = Qnil;
   c.val = Qnil;
   c.backlist = backtrace_list;
-  c.handlerlist = handlerlist;
-  c.lisp_eval_depth = lisp_eval_depth;
+  c.f_handlerlist = handlerlist;
+  c.f_lisp_eval_depth = lisp_eval_depth;
   c.pdlcount = SPECPDL_INDEX ();
   c.poll_suppress_count = poll_suppress_count;
   c.interrupt_input_blocked = interrupt_input_blocked;
@@ -1324,8 +1324,8 @@ internal_condition_case_1 (Lisp_Object (*bfun) (Lisp_Object), Lisp_Object arg,
   c.tag = Qnil;
   c.val = Qnil;
   c.backlist = backtrace_list;
-  c.handlerlist = handlerlist;
-  c.lisp_eval_depth = lisp_eval_depth;
+  c.f_handlerlist = handlerlist;
+  c.f_lisp_eval_depth = lisp_eval_depth;
   c.pdlcount = SPECPDL_INDEX ();
   c.poll_suppress_count = poll_suppress_count;
   c.interrupt_input_blocked = interrupt_input_blocked;
@@ -1366,8 +1366,8 @@ internal_condition_case_2 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object),
   c.tag = Qnil;
   c.val = Qnil;
   c.backlist = backtrace_list;
-  c.handlerlist = handlerlist;
-  c.lisp_eval_depth = lisp_eval_depth;
+  c.f_handlerlist = handlerlist;
+  c.f_lisp_eval_depth = lisp_eval_depth;
   c.pdlcount = SPECPDL_INDEX ();
   c.poll_suppress_count = poll_suppress_count;
   c.interrupt_input_blocked = interrupt_input_blocked;
@@ -1410,8 +1410,8 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *),
   c.tag = Qnil;
   c.val = Qnil;
   c.backlist = backtrace_list;
-  c.handlerlist = handlerlist;
-  c.lisp_eval_depth = lisp_eval_depth;
+  c.f_handlerlist = handlerlist;
+  c.f_lisp_eval_depth = lisp_eval_depth;
   c.pdlcount = SPECPDL_INDEX ();
   c.poll_suppress_count = poll_suppress_count;
   c.interrupt_input_blocked = interrupt_input_blocked;
diff --git a/src/lisp.h b/src/lisp.h
index 025736e..2cf8499 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2014,10 +2014,6 @@ struct specbinding
     Lisp_Object unused;		/* Dividing by 16 is faster than by 12 */
   };
 
-extern struct specbinding *specpdl;
-extern struct specbinding *specpdl_ptr;
-extern ptrdiff_t specpdl_size;
-
 #define SPECPDL_INDEX()	(specpdl_ptr - specpdl)
 
 /* Everything needed to describe an active condition case.  */
@@ -2070,8 +2066,8 @@ struct catchtag
   struct gcpro *gcpro;
   jmp_buf jmp;
   struct backtrace *backlist;
-  struct handler *handlerlist;
-  EMACS_INT lisp_eval_depth;
+  struct handler *f_handlerlist;
+  EMACS_INT f_lisp_eval_depth;
   ptrdiff_t pdlcount;
   int poll_suppress_count;
   int interrupt_input_blocked;
@@ -2080,10 +2076,6 @@ struct catchtag
 
 extern Lisp_Object memory_signal_data;
 
-/* An address near the bottom of the stack.
-   Tells GC how to save a copy of the stack.  */
-extern char *stack_bottom;
-
 /* Check quit-flag and quit if it is non-nil.
    Typing C-g does not directly cause a quit; it only sets Vquit_flag.
    So the program needs to do QUIT at times when it is safe to quit.
@@ -2139,8 +2131,6 @@ extern Lisp_Object Vascii_canon_table;
    Every function that can call Feval must protect in this fashion all
    Lisp_Object variables whose contents will be used again.  */
 
-extern struct gcpro *gcprolist;
-
 struct gcpro
 {
   struct gcpro *next;
@@ -2245,8 +2235,6 @@ struct gcpro
 
 #else
 
-extern int gcpro_level;
-
 #define GCPRO1(varname) \
  {gcpro1.next = gcprolist; gcpro1.var = &varname; gcpro1.nvars = 1; \
   gcpro1.level = gcpro_level++; \
@@ -2728,7 +2716,6 @@ extern void refill_memory_reserve (void);
 #endif
 extern const char *pending_malloc_warning;
 extern Lisp_Object zero_vector;
-extern Lisp_Object *stack_base;
 extern EMACS_INT consing_since_gc;
 extern EMACS_INT gc_relative_threshold;
 extern EMACS_INT memory_full_cons_threshold;
@@ -2914,10 +2901,6 @@ extern Lisp_Object Vautoload_queue;
 extern Lisp_Object Vsignaling_function;
 extern Lisp_Object inhibit_lisp_code;
 extern int handling_signal;
-#if BYTE_MARK_STACK
-extern struct catchtag *catchlist;
-extern struct handler *handlerlist;
-#endif
 /* To run a normal hook, use the appropriate function from the list below.
    The calling convention:
 
@@ -3226,7 +3209,6 @@ extern int read_bytecode_char (int);
 /* Defined in bytecode.c */
 extern Lisp_Object Qbytecode;
 extern void syms_of_bytecode (void);
-extern struct byte_stack *byte_stack_list;
 #if BYTE_MARK_STACK
 extern void mark_byte_stack (void);
 #endif
@@ -3540,6 +3522,7 @@ extern void *record_xmalloc (size_t);
 
 
 #include "globals.h"
+#include "thread.h"
 
 /* Check whether it's time for GC, and run it if so.  */
 
diff --git a/src/regex.c b/src/regex.c
index afe3751..29b884e 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -1236,12 +1236,14 @@ print_double_string (where, string1, size1, string2, size2)
 # define IF_LINT(Code) /* empty */
 #endif
 \f
+#ifndef emacs
 /* Set by `re_set_syntax' to the current regexp syntax to recognize.  Can
    also be assigned to arbitrarily: each pattern buffer stores its own
    syntax, so it can be changed between regex compilations.  */
 /* This has no initializer because initialized variables in Emacs
    become read-only after dumping.  */
 reg_syntax_t re_syntax_options;
+#endif
 
 
 /* Specify the precise syntax of regexps for compilation.  This provides
@@ -1261,8 +1263,10 @@ re_set_syntax (reg_syntax_t syntax)
 }
 WEAK_ALIAS (__re_set_syntax, re_set_syntax)
 
+#ifndef emacs
 /* Regexp to use to replace spaces, or NULL meaning don't.  */
 static re_char *whitespace_regexp;
+#endif
 
 void
 re_set_whitespace_regexp (const char *regexp)
@@ -4901,12 +4905,6 @@ re_match (struct re_pattern_buffer *bufp, const char *string,
 WEAK_ALIAS (__re_match, re_match)
 #endif /* not emacs */
 
-#ifdef emacs
-/* In Emacs, this is the string or buffer in which we
-   are matching.  It is used for looking up syntax properties.  */
-Lisp_Object re_match_object;
-#endif
-
 /* re_match_2 matches the compiled pattern in BUFP against the
    the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
    and SIZE2, respectively).  We start matching at POS, and stop
diff --git a/src/regex.h b/src/regex.h
index e0ede01..91886a8 100644
--- a/src/regex.h
+++ b/src/regex.h
@@ -166,12 +166,12 @@ typedef unsigned long int reg_syntax_t;
    some interfaces).  When a regexp is compiled, the syntax used is
    stored in the pattern buffer, so changing this does not affect
    already-compiled regexps.  */
-extern reg_syntax_t re_syntax_options;
+/* extern reg_syntax_t re_syntax_options; */
 
 #ifdef emacs
 /* In Emacs, this is the string or buffer in which we
    are matching.  It is used for looking up syntax properties.  */
-extern Lisp_Object re_match_object;
+/* extern Lisp_Object re_match_object; */
 #endif
 
 \f
diff --git a/src/search.c b/src/search.c
index 004e599..5df01f6 100644
--- a/src/search.c
+++ b/src/search.c
@@ -42,7 +42,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 struct regexp_cache
 {
   struct regexp_cache *next;
-  Lisp_Object regexp, whitespace_regexp;
+  Lisp_Object regexp, f_whitespace_regexp;
   /* Syntax table for which the regexp applies.  We need this because
      of character classes.  If this is t, then the compiled pattern is valid
      for any syntax-table.  */
@@ -77,12 +77,12 @@ static struct regexp_cache *searchbuf_head;
    to call re_set_registers after compiling a new pattern or after
    setting the match registers, so that the regex functions will be
    able to free or re-allocate it properly.  */
-static struct re_registers search_regs;
+/* static struct re_registers search_regs; */
 
 /* The buffer in which the last search was performed, or
    Qt if the last search was done in a string;
    Qnil if no searching has been done yet.  */
-static Lisp_Object last_thing_searched;
+/* static Lisp_Object last_thing_searched; */
 
 /* Error condition signaled when regexp compile_pattern fails.  */
 static Lisp_Object Qinvalid_regexp;
@@ -129,9 +129,9 @@ compile_pattern_1 (struct regexp_cache *cp, Lisp_Object pattern, Lisp_Object tra
   cp->buf.multibyte = STRING_MULTIBYTE (pattern);
   cp->buf.charset_unibyte = charset_unibyte;
   if (STRINGP (Vsearch_spaces_regexp))
-    cp->whitespace_regexp = Vsearch_spaces_regexp;
+    cp->f_whitespace_regexp = Vsearch_spaces_regexp;
   else
-    cp->whitespace_regexp = Qnil;
+    cp->f_whitespace_regexp = Qnil;
 
   /* rms: I think BLOCK_INPUT is not needed here any more,
      because regex.c defines malloc to call xmalloc.
@@ -230,7 +230,7 @@ compile_pattern (Lisp_Object pattern, struct re_registers *regp, Lisp_Object tra
 	  && cp->posix == posix
 	  && (EQ (cp->syntax_table, Qt)
 	      || EQ (cp->syntax_table, BVAR (current_buffer, syntax_table)))
-	  && !NILP (Fequal (cp->whitespace_regexp, Vsearch_spaces_regexp))
+	  && !NILP (Fequal (cp->f_whitespace_regexp, Vsearch_spaces_regexp))
 	  && cp->buf.charset_unibyte == charset_unibyte)
 	break;
 
@@ -2938,9 +2938,9 @@ If optional arg RESEAT is non-nil, make markers on LIST point nowhere.  */)
 
 /* If non-zero the match data have been saved in saved_search_regs
    during the execution of a sentinel or filter. */
-static int search_regs_saved;
-static struct re_registers saved_search_regs;
-static Lisp_Object saved_last_thing_searched;
+/* static int search_regs_saved; */
+/* static struct re_registers saved_search_regs; */
+/* static Lisp_Object saved_last_thing_searched; */
 
 /* Called from Flooking_at, Fstring_match, search_buffer, Fstore_match_data
    if asynchronous code (filter or sentinel) is running. */
@@ -3044,10 +3044,10 @@ syms_of_search (void)
       searchbufs[i].buf.buffer = xmalloc (100);
       searchbufs[i].buf.fastmap = searchbufs[i].fastmap;
       searchbufs[i].regexp = Qnil;
-      searchbufs[i].whitespace_regexp = Qnil;
+      searchbufs[i].f_whitespace_regexp = Qnil;
       searchbufs[i].syntax_table = Qnil;
       staticpro (&searchbufs[i].regexp);
-      staticpro (&searchbufs[i].whitespace_regexp);
+      staticpro (&searchbufs[i].f_whitespace_regexp);
       staticpro (&searchbufs[i].syntax_table);
       searchbufs[i].next = (i == REGEXP_CACHE_SIZE-1 ? 0 : &searchbufs[i+1]);
     }
diff --git a/src/thread.c b/src/thread.c
new file mode 100644
index 0000000..0bd97b4
--- /dev/null
+++ b/src/thread.c
@@ -0,0 +1,26 @@
+/* Threading code.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
+
+
+#include <config.h>
+#include <setjmp.h>
+#include "lisp.h"
+
+struct thread_state the_only_thread;
+
+struct thread_state *current_thread = &the_only_thread;
diff --git a/src/thread.h b/src/thread.h
new file mode 100644
index 0000000..b2eb04d
--- /dev/null
+++ b/src/thread.h
@@ -0,0 +1,140 @@
+/* Thread definitions
+   Copyright (C) 2012 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef THREAD_H
+#define THREAD_H
+
+#include "regex.h"
+
+struct thread_state
+{
+  /* The buffer in which the last search was performed, or
+     Qt if the last search was done in a string;
+     Qnil if no searching has been done yet.  */
+  Lisp_Object m_last_thing_searched;
+#define last_thing_searched (current_thread->m_last_thing_searched)
+
+  Lisp_Object m_saved_last_thing_searched;
+#define saved_last_thing_searched (current_thread->m_saved_last_thing_searched)
+
+  /* m_gcprolist must be the first non-lisp field.  */
+  /* Recording what needs to be marked for gc.  */
+  struct gcpro *m_gcprolist;
+#define gcprolist (current_thread->m_gcprolist)
+
+  /* A list of currently active byte-code execution value stacks.
+     Fbyte_code adds an entry to the head of this list before it starts
+     processing byte-code, and it removed the entry again when it is
+     done.  Signalling an error truncates the list analoguous to
+     gcprolist.  */
+  struct byte_stack *m_byte_stack_list;
+#define byte_stack_list (current_thread->m_byte_stack_list)
+
+  /* An address near the bottom of the stack.
+     Tells GC how to save a copy of the stack.  */
+  char *m_stack_bottom;
+#define stack_bottom (current_thread->m_stack_bottom)
+
+  /* An address near the top of the stack.  */
+  char *stack_top;
+
+  struct backtrace *m_backtrace_list;
+#define backtrace_list (current_thread->m_backtrace_list)
+
+  struct catchtag *m_catchlist;
+#define catchlist (current_thread->m_catchlist)
+
+  /* Chain of condition handlers currently in effect.
+     The elements of this chain are contained in the stack frames
+     of Fcondition_case and internal_condition_case.
+     When an error is signaled (by calling Fsignal, below),
+     this chain is searched for an element that applies.  */
+  struct handler *m_handlerlist;
+#define handlerlist (current_thread->m_handlerlist)
+
+  /* Count levels of GCPRO to detect failure to UNGCPRO.  */
+  int m_gcpro_level;
+#define gcpro_level (current_thread->m_gcpro_level)
+
+  /* Current number of specbindings allocated in specpdl.  */
+  ptrdiff_t m_specpdl_size;
+#define specpdl_size (current_thread->m_specpdl_size)
+
+  /* Pointer to beginning of specpdl.  */
+  struct specbinding *m_specpdl;
+#define specpdl (current_thread->m_specpdl)
+
+  /* Pointer to first unused element in specpdl.  */
+  struct specbinding *m_specpdl_ptr;
+#define specpdl_ptr (current_thread->m_specpdl_ptr)
+
+  /* Depth in Lisp evaluations and function calls.  */
+  EMACS_INT m_lisp_eval_depth;
+#define lisp_eval_depth (current_thread->m_lisp_eval_depth)
+
+  /* This points to the current buffer.  */
+  struct buffer *m_current_buffer;
+#define current_buffer (current_thread->m_current_buffer)
+
+  /* Every call to re_match, etc., must pass &search_regs as the regs
+     argument unless you can show it is unnecessary (i.e., if re_match
+     is certainly going to be called again before region-around-match
+     can be called).
+
+     Since the registers are now dynamically allocated, we need to make
+     sure not to refer to the Nth register before checking that it has
+     been allocated by checking search_regs.num_regs.
+
+     The regex code keeps track of whether it has allocated the search
+     buffer using bits in the re_pattern_buffer.  This means that whenever
+     you compile a new pattern, it completely forgets whether it has
+     allocated any registers, and will allocate new registers the next
+     time you call a searching or matching function.  Therefore, we need
+     to call re_set_registers after compiling a new pattern or after
+     setting the match registers, so that the regex functions will be
+     able to free or re-allocate it properly.  */
+  struct re_registers m_search_regs;
+#define search_regs (current_thread->m_search_regs)
+
+  /* If non-zero the match data have been saved in saved_search_regs
+     during the execution of a sentinel or filter. */
+  int m_search_regs_saved;
+#define search_regs_saved (current_thread->m_search_regs_saved)
+
+  struct re_registers m_saved_search_regs;
+#define saved_search_regs (current_thread->m_saved_search_regs)
+
+  /* This is the string or buffer in which we
+     are matching.  It is used for looking up syntax properties.  */
+  Lisp_Object m_re_match_object;
+#define re_match_object (current_thread->m_re_match_object)
+
+  /* Set by `re_set_syntax' to the current regexp syntax to recognize.  Can
+     also be assigned to arbitrarily: each pattern buffer stores its own
+     syntax, so it can be changed between regex compilations.  */
+  reg_syntax_t m_re_syntax_options;
+#define re_syntax_options (current_thread->m_re_syntax_options)
+
+  /* Regexp to use to replace spaces, or NULL meaning don't.  */
+  /*re_char*/ unsigned char *m_whitespace_regexp;
+#define whitespace_regexp (current_thread->m_whitespace_regexp)
+};
+
+extern struct thread_state *current_thread;
+
+#endif /* THREAD_H */
diff --git a/src/window.c b/src/window.c
index 1348eab..dee1216 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5296,7 +5296,7 @@ struct save_window_data
     struct vectorlike_header header;
     Lisp_Object selected_frame;
     Lisp_Object current_window;
-    Lisp_Object current_buffer;
+    Lisp_Object f_current_buffer;
     Lisp_Object minibuf_scroll_window;
     Lisp_Object minibuf_selected_window;
     Lisp_Object root_window;
@@ -5377,7 +5377,7 @@ the return value is nil.  Otherwise the value is t.  */)
   data = (struct save_window_data *) XVECTOR (configuration);
   saved_windows = XVECTOR (data->saved_windows);
 
-  new_current_buffer = data->current_buffer;
+  new_current_buffer = data->f_current_buffer;
   if (NILP (BVAR (XBUFFER (new_current_buffer), name)))
     new_current_buffer = Qnil;
   else
@@ -6012,7 +6012,7 @@ saved by this function.  */)
   data->frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
   data->selected_frame = selected_frame;
   data->current_window = FRAME_SELECTED_WINDOW (f);
-  XSETBUFFER (data->current_buffer, current_buffer);
+  XSETBUFFER (data->f_current_buffer, current_buffer);
   data->minibuf_scroll_window = minibuf_level > 0 ? Vminibuf_scroll_window : Qnil;
   data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil;
   data->root_window = FRAME_ROOT_WINDOW (f);
@@ -6416,7 +6416,7 @@ compare_window_configurations (Lisp_Object configuration1, Lisp_Object configura
       || d1->frame_lines != d2->frame_lines
       || d1->frame_menu_bar_lines != d2->frame_menu_bar_lines
       || !EQ (d1->selected_frame, d2->selected_frame)
-      || !EQ (d1->current_buffer, d2->current_buffer)
+      || !EQ (d1->f_current_buffer, d2->f_current_buffer)
       || (!ignore_positions
 	  && (!EQ (d1->minibuf_scroll_window, d2->minibuf_scroll_window)
 	      || !EQ (d1->minibuf_selected_window, d2->minibuf_selected_window)))
-- 
1.7.7.6




^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 01/10] move some globals into a thread object
  2012-08-09 19:37 [PATCH 01/10] move some globals into a thread object Tom Tromey
@ 2012-08-10  1:18 ` Stefan Monnier
  2012-08-13 14:19   ` Tom Tromey
  0 siblings, 1 reply; 3+ messages in thread
From: Stefan Monnier @ 2012-08-10  1:18 UTC (permalink / raw
  To: Tom Tromey; +Cc: Emacs discussions

> The #defines mean that this patch also has to rename a few fields
> whose names clash with the defines.

I'd rather rename the globals (although I understand it will probably
result in a larger patch), because I'd rather limit the impact of those
#defines.  If you ever create a local variable (or a struct field) named
`current_buffer' somewhere, it might take you a good while to figure out
why your code is misbehaving.


        Stefan



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 01/10] move some globals into a thread object
  2012-08-10  1:18 ` Stefan Monnier
@ 2012-08-13 14:19   ` Tom Tromey
  0 siblings, 0 replies; 3+ messages in thread
From: Tom Tromey @ 2012-08-13 14:19 UTC (permalink / raw
  To: Stefan Monnier; +Cc: Emacs discussions

>>>>> "Stefan" == Stefan Monnier <monnier@iro.umontreal.ca> writes:

Tom> The #defines mean that this patch also has to rename a few fields
Tom> whose names clash with the defines.

Stefan> I'd rather rename the globals (although I understand it will probably
Stefan> result in a larger patch), because I'd rather limit the impact of those
Stefan> #defines.

Ok, I will do this, but please don't let this block looking at the other
patches.  This particular patch is one of the least interesting ones of
the series.

The big reason not to do this is just that reindenting everything is
tedious.  There are thousands of spots to check for line wrapping :-(
Just thinking about it makes me want to take a different approach instead.

Stefan> If you ever create a local variable (or a struct field) named
Stefan> `current_buffer' somewhere, it might take you a good while to
Stefan> figure out why your code is misbehaving.

FWIW, newish versions of gcc give much better error messages for
problems arising from macro expansion.

Tom



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-08-13 14:19 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-09 19:37 [PATCH 01/10] move some globals into a thread object Tom Tromey
2012-08-10  1:18 ` Stefan Monnier
2012-08-13 14:19   ` Tom Tromey

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.