Subject: bug#4470: 23.1; threaded interpreter

From: Tom Tromey <[email-masked]>
Date: Thu, 17 Sep 2009 14:56:58 -0600

Please write in English if possible, because the Emacs maintainers
usually do not have translators to read other languages for them.

Your bug report will be posted to the [email-masked] mailing list,
and to the gnu.emacs.bug news group.

Please describe exactly what actions triggered the bug
and the precise symptoms of the bug:

I've appended the threaded interpreter patch.

If Emacs crashed, and you have the Emacs process in the gdb debugger,
please include the output from the following gdb commands:
    `bt full' and `xbacktrace'.
If you would like to further debug the crash, please read the file
/usr/share/emacs/23.1/etc/DEBUG for instructions.

In GNU Emacs 23.1.1 (i386-redhat-linux-gnu, GTK+ Version 2.16.5)
 of 2009-08-26 on x86-2.fedora.phx.redhat.com
Windowing system distributor `The X.Org Foundation', version 11.0.10601901
configured using `configure  '--build=i386-redhat-linux-gnu' '--host=i386-redhat-linux-gnu' '--target=i586-redhat-linux-gnu' '--program-prefix=' '--prefix=/usr' '--exec-prefix=/usr' '--bindir=/usr/bin' '--sbindir=/usr/sbin' '--sysconfdir=/etc' '--datadir=/usr/share' '--includedir=/usr/include' '--libdir=/usr/lib' '--libexecdir=/usr/libexec' '--localstatedir=/var' '--sharedstatedir=/var/lib' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--with-dbus' '--with-gif' '--with-jpeg' '--with-png' '--with-rsvg' '--with-tiff' '--with-xft' '--with-xpm' '--with-x-toolkit=gtk' 'build_alias=i386-redhat-linux-gnu' 'host_alias=i386-redhat-linux-gnu' 'target_alias=i586-redhat-linux-gnu' 'CFLAGS=-DMAIL_USE_LOCKF -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i586 -mtune=generic -fasynchronous-unwind-tables''

Important settings:
  value of $LC_ALL: nil
  value of $LC_COLLATE: nil
  value of $LC_CTYPE: nil
  value of $LC_MESSAGES: nil
  value of $LC_MONETARY: nil
  value of $LC_NUMERIC: nil
  value of $LC_TIME: nil
  value of $LANG: en_US.UTF-8
  value of $XMODIFIERS: nil
  locale-coding-system: utf-8-unix
  default-enable-multibyte-characters: t

Major mode: Group

Minor modes in effect:
  gnus-agent-mode: t
  shell-dirtrack-mode: t
  erc-list-mode: t
  erc-menu-mode: t
  erc-autojoin-mode: t
  erc-ring-mode: t
  erc-pcomplete-mode: t
  erc-track-mode: t
  erc-track-minor-mode: t
  erc-match-mode: t
  erc-button-mode: t
  erc-fill-mode: t
  erc-stamp-mode: t
  erc-netsplit-mode: t
  erc-spelling-mode: t
  erc-truncate-mode: t
  diff-auto-refine-mode: t
  gnus-undo-mode: t
  erc-status-mode: t
  erc-services-mode: t
  erc-networks-mode: t
  erc-irccontrols-mode: t
  erc-noncommands-mode: t
  erc-move-to-prompt-mode: t
  erc-readonly-mode: t
  tooltip-mode: t
  mouse-wheel-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  global-auto-composition-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: t
  transient-mark-mode: t

Recent input:
C-n C-w C-x C-o C-u C-p C-u C-p C-p C-p C-p C-e g e 
n e r a t e d SPC c o d e . C-f C-f C-z o C-z o C-o 
C-o I SPC a m SPC n o t SPC s u r e SPC v m g e n SPC 
i s SPC a SPC <M-backspace> t h e SPC b e s t SPC t 
r a d e o f f . SPC SPC C-a C-k I S-SPC l i k e SPC 
v m g e n SPC b u t SPC C-a C-k C-x C-o C-u C-n C-n 
C-n C-n M-f M-f M-b <M-backspace> <M-backspace> M-c 
M-f <M-backspace> w o u l d SPC b e M-f M-d M-d M-d 
SPC t o M-q C-n C-e SPC S-SPC S o , SPC <M-backspace> 
M-q C-z o <f10> <f10> <f10> <f10> <f10> <f10> C-z o 
M-a M-k M-a M-k T h i s SPC i s SPC a SPC b i t SPC 
m o r e SPC s p e c <M-backspace> s p e c i f i c SPC 
t h a n SPC y o u r SPC t y p i c a l SPC G C C S-SPC 
o p t i m i z a t i o n , SPC t h o u g h . <return> 
<return> I SPC d o n ' t SPC t h i n k SPC t h a t 
SPC c o n s i d e r a t i o n s SPC o C-a C-u C-u C-p 
C-x k <return> y e s <return> C-c b E q s M-x r e p 
o r t - e m <tab> b <tab> <return>

Recent messages:
Mark activated
Auto-saving...done
Mark set
Auto-saving...done
Expiring articles...done
(No changes need to be saved)
Saving /home/tromey/.newsrc.eld...
Saving file /home/tromey/.newsrc.eld...
Wrote /home/tromey/.newsrc.eld
Saving /home/tromey/.newsrc.eld...done

Tom

2009-09-17  Tom Tromey  <[email-masked]>

	* bytecode.c (BYTE_CODE_THREADED): New define.
	(Bvarref1, Bvarref2, Bvarref3, Bvarref4, Bvarref5, Bvarref6)
	(Bvarref7, Bvarset1, Bvarset2, Bvarset3, Bvarset4, Bvarset5)
	(Bvarset6, Bvarset7, Bvarbind1, Bvarbind2, Bvarbind3, Bvarbind4)
	(Bvarbind5, Bvarbind6, Bvarbind7, Bcall1, Bcall2, Bcall3)
	(Bcall4, Bcall5, Bcall6, Bcall7, Bunbind1, Bunbind2, Bunbind3)
	(Bunbind4, Bunbind5, Bunbind6, Bunbind7): New defines.
	(CASE, LABEL, NEXT, FIRST, CASE_DEFAULT, CASE_ABORT): New
	defines.
	(Fbyte_code): Use indirect threading.  Rewrite switch and case
	labels.

diff --git a/src/bytecode.c b/src/bytecode.c
index 43d972e..bd69a89 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -54,6 +54,13 @@ by Hallvard:
 /* #define BYTE_CODE_SAFE */
 /* #define BYTE_CODE_METER */
 
+/* If BYTE_CODE_THREADED is defined, then the interpreter will be
+   indirect threaded, using GCC's computed goto extension.  This is
+   incompatible with BYTE_CODE_SAFE and BYTE_CODE_METER.  */
+#if defined (__GNUC__) && !defined (BYTE_CODE_SAFE) && !defined (BYTE_CODE_METER)
+#define BYTE_CODE_THREADED
+#endif
+
 
 #ifdef BYTE_CODE_METER
 
@@ -90,10 +97,45 @@ Lisp_Object Qbytecode;
 /*  Byte codes: */
 
 #define Bvarref 010
+#define Bvarref1 011
+#define Bvarref2 012
+#define Bvarref3 013
+#define Bvarref4 014
+#define Bvarref5 015
+#define Bvarref6 016
+#define Bvarref7 017
 #define Bvarset 020
+#define Bvarset1 021
+#define Bvarset2 022
+#define Bvarset3 023
+#define Bvarset4 024
+#define Bvarset5 025
+#define Bvarset6 026
+#define Bvarset7 027
 #define Bvarbind 030
+#define Bvarbind1 031
+#define Bvarbind2 032
+#define Bvarbind3 033
+#define Bvarbind4 034
+#define Bvarbind5 035
+#define Bvarbind6 036
+#define Bvarbind7 037
 #define Bcall 040
+#define Bcall1 041
+#define Bcall2 042
+#define Bcall3 043
+#define Bcall4 044
+#define Bcall5 045
+#define Bcall6 046
+#define Bcall7 047
 #define Bunbind 050
+#define Bunbind1 051
+#define Bunbind2 052
+#define Bunbind3 053
+#define Bunbind4 054
+#define Bunbind5 055
+#define Bunbind6 056
+#define Bunbind7 057
 
 #define Bnth 070
 #define Bsymbolp 071
@@ -463,27 +505,324 @@ If the third argument is incorrect, Emacs may crash.  */)
       this_op = op = FETCH;
       METER_CODE (prev_op, op);
 #else
+#ifndef BYTE_CODE_THREADED
       op = FETCH;
 #endif
+#endif
+
+#ifdef BYTE_CODE_THREADED
+#define CASE(OP) insn_ ## OP
+#define LABEL(OP) &&insn_ ## OP
+#define NEXT goto *(targets[op = FETCH])
+#define FIRST NEXT;
+#define CASE_DEFAULT
+#define CASE_ABORT CASE (default)
+#else
+#define CASE(OP) case OP
+#define NEXT break
+#define FIRST switch (op)
+#define CASE_DEFAULT case 255: default:
+#define CASE_ABORT case 0
+#endif
+
+#ifdef BYTE_CODE_THREADED
+      static const void *const targets[256] =
+	{
+	  LABEL (default),	/* 0 */
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),	/* 7 */
+	  LABEL (Bvarref),
+	  LABEL (Bvarref1),
+	  LABEL (Bvarref2),
+	  LABEL (Bvarref3),
+	  LABEL (Bvarref4),
+	  LABEL (Bvarref5),
+	  LABEL (Bvarref6),
+	  LABEL (Bvarref7),
+	  LABEL (Bvarset),
+	  LABEL (Bvarset1),
+	  LABEL (Bvarset2),
+	  LABEL (Bvarset3),
+	  LABEL (Bvarset4),
+	  LABEL (Bvarset5),
+	  LABEL (Bvarset6),
+	  LABEL (Bvarset7),
+	  LABEL (Bvarbind),
+	  LABEL (Bvarbind1),
+	  LABEL (Bvarbind2),
+	  LABEL (Bvarbind3),
+	  LABEL (Bvarbind4),
+	  LABEL (Bvarbind5),
+	  LABEL (Bvarbind6),
+	  LABEL (Bvarbind7),
+	  LABEL (Bcall),
+	  LABEL (Bcall1),
+	  LABEL (Bcall2),
+	  LABEL (Bcall3),
+	  LABEL (Bcall4),
+	  LABEL (Bcall5),
+	  LABEL (Bcall6),
+	  LABEL (Bcall7),
+	  LABEL (Bunbind),
+	  LABEL (Bunbind1),
+	  LABEL (Bunbind2),
+	  LABEL (Bunbind3),
+	  LABEL (Bunbind4),
+	  LABEL (Bunbind5),
+	  LABEL (Bunbind6),
+	  LABEL (Bunbind7),
+	  LABEL (default),	/* 060 */
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),	/* 067 */
+	  LABEL (Bnth),
+	  LABEL (Bsymbolp),
+	  LABEL (Bconsp),
+	  LABEL (Bstringp),
+	  LABEL (Blistp),
+	  LABEL (Beq),
+	  LABEL (Bmemq),
+	  LABEL (Bnot),
+	  LABEL (Bcar),
+	  LABEL (Bcdr),
+	  LABEL (Bcons),
+	  LABEL (Blist1),
+	  LABEL (Blist2),
+	  LABEL (Blist3),
+	  LABEL (Blist4),
+	  LABEL (Blength),
+	  LABEL (Baref),
+	  LABEL (Baset),
+	  LABEL (Bsymbol_value),
+	  LABEL (Bsymbol_function),
+	  LABEL (Bset),
+	  LABEL (Bfset),
+	  LABEL (Bget),
+	  LABEL (Bsubstring),
+	  LABEL (Bconcat2),
+	  LABEL (Bconcat3),
+	  LABEL (Bconcat4),
+	  LABEL (Bsub1),
+	  LABEL (Badd1),
+	  LABEL (Beqlsign),
+	  LABEL (Bgtr),
+	  LABEL (Blss),
+	  LABEL (Bleq),
+	  LABEL (Bgeq),
+	  LABEL (Bdiff),
+	  LABEL (Bnegate),
+	  LABEL (Bplus),
+	  LABEL (Bmax),
+	  LABEL (Bmin),
+	  LABEL (Bmult),
+	  LABEL (Bpoint),
+	  LABEL (Bsave_current_buffer),
+	  LABEL (Bgoto_char),
+	  LABEL (Binsert),
+	  LABEL (Bpoint_max),
+	  LABEL (Bpoint_min),
+	  LABEL (Bchar_after),
+	  LABEL (Bfollowing_char),
+	  LABEL (Bpreceding_char),
+	  LABEL (Bcurrent_column),
+	  LABEL (Bindent_to),
+	  LABEL (Bscan_buffer),
+	  LABEL (Beolp),
+	  LABEL (Beobp),
+	  LABEL (Bbolp),
+	  LABEL (Bbobp),
+	  LABEL (Bcurrent_buffer),
+	  LABEL (Bset_buffer),
+	  LABEL (Bsave_current_buffer_1),
+	  LABEL (Bset_mark),
+	  LABEL (Binteractive_p),
+	  LABEL (Bforward_char),
+	  LABEL (Bforward_word),
+	  LABEL (Bskip_chars_forward),
+	  LABEL (Bskip_chars_backward),
+	  LABEL (Bforward_line),
+	  LABEL (Bchar_syntax),
+	  LABEL (Bbuffer_substring),
+	  LABEL (Bdelete_region),
+	  LABEL (Bnarrow_to_region),
+	  LABEL (Bwiden),
+	  LABEL (Bend_of_line),
+	  LABEL (default),	/* 0200 */
+	  LABEL (Bconstant2),
+	  LABEL (Bgoto),
+	  LABEL (Bgotoifnil),
+	  LABEL (Bgotoifnonnil),
+	  LABEL (Bgotoifnilelsepop),
+	  LABEL (Bgotoifnonnilelsepop),
+	  LABEL (Breturn),
+	  LABEL (Bdiscard),
+	  LABEL (Bdup),
+	  LABEL (Bsave_excursion),
+	  LABEL (Bsave_window_excursion),
+	  LABEL (Bsave_restriction),
+	  LABEL (Bcatch),
+	  LABEL (Bunwind_protect),
+	  LABEL (Bcondition_case),
+	  LABEL (Btemp_output_buffer_setup),
+	  LABEL (Btemp_output_buffer_show),
+	  LABEL (Bunbind_all),
+	  LABEL (Bset_marker),
+	  LABEL (Bmatch_beginning),
+	  LABEL (Bmatch_end),
+	  LABEL (Bupcase),
+	  LABEL (Bdowncase),
+	  LABEL (Bstringeqlsign),
+	  LABEL (Bstringlss),
+	  LABEL (Bequal),
+	  LABEL (Bnthcdr),
+	  LABEL (Belt),
+	  LABEL (Bmember),
+	  LABEL (Bassq),
+	  LABEL (Bnreverse),
+	  LABEL (Bsetcar),
+	  LABEL (Bsetcdr),
+	  LABEL (Bcar_safe),
+	  LABEL (Bcdr_safe),
+	  LABEL (Bnconc),
+	  LABEL (Bquo),
+	  LABEL (Brem),
+	  LABEL (Bnumberp),
+	  LABEL (Bintegerp),
+	  LABEL (default),	/* 0251 */
+	  LABEL (BRgoto),
+	  LABEL (BRgotoifnil),
+	  LABEL (BRgotoifnonnil),
+	  LABEL (BRgotoifnilelsepop),
+	  LABEL (BRgotoifnonnilelsepop),
+	  LABEL (BlistN),
+	  LABEL (BconcatN),
+	  LABEL (BinsertN),
+	  LABEL (default),	/* 0262 */
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),	/* 0270 */
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),
+	  LABEL (default),	/* 0277 */
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant),
+	  LABEL (Bconstant)
+	};
+#endif
+
+#if 0
+      /* Sanity checks that are useful if you modify the table.  */
+      if (targets[Bsymbol_value] != LABEL (Bsymbol_value))
+	abort ();
+      if (targets[Bconstant2] != LABEL (Bconstant2))
+	abort ();
+      if (targets[Bnegate] != LABEL (Bnegate))
+	abort ();
+      if (targets[BinsertN] != LABEL (BinsertN))
+	abort ();
+      if (targets[0277] != LABEL (default))
+	abort ();
+      if (targets[Bconstant-1] == LABEL (Bconstant))
+	abort ();
+      if (targets[Bconstant] != LABEL (Bconstant))
+	abort ();
+#endif
 
-      switch (op)
+      FIRST
 	{
-	case Bvarref + 7:
+	CASE (Bvarref7):
 	  op = FETCH2;
 	  goto varref;
 
-	case Bvarref:
-	case Bvarref + 1:
-	case Bvarref + 2:
-	case Bvarref + 3:
-	case Bvarref + 4:
-	case Bvarref + 5:
+	CASE (Bvarref):
+	CASE (Bvarref1):
+	CASE (Bvarref2):
+	CASE (Bvarref3):
+	CASE (Bvarref4):
+	CASE (Bvarref5):
 	  op = op - Bvarref;
 	  goto varref;
 
 	/* This seems to be the most frequently executed byte-code
 	   among the Bvarref's, so avoid a goto here.  */
-	case Bvarref+6:
+	CASE (Bvarref6):
 	  op = FETCH;
 	varref:
 	  {
@@ -507,10 +846,10 @@ If the third argument is incorrect, Emacs may crash.  */)
 		AFTER_POTENTIAL_GC ();
 	      }
 	    PUSH (v2);
-	    break;
+	    NEXT;
 	  }
 
-	case Bgotoifnil:
+	CASE (Bgotoifnil):
 	  {
 	    Lisp_Object v1;
 	    MAYBE_GC ();
@@ -522,57 +861,57 @@ If the third argument is incorrect, Emacs may crash.  */)
 		CHECK_RANGE (op);
 		stack.pc = stack.byte_string_start + op;
 	      }
-	    break;
+	    NEXT;
 	  }
 
-	case Bcar:
+	CASE (Bcar):
 	  {
 	    Lisp_Object v1;
 	    v1 = TOP;
 	    TOP = CAR (v1);
-	    break;
+	    NEXT;
 	  }
 
-	case Beq:
+	CASE (Beq):
 	  {
 	    Lisp_Object v1;
 	    v1 = POP;
 	    TOP = EQ (v1, TOP) ? Qt : Qnil;
-	    break;
+	    NEXT;
 	  }
 
-	case Bmemq:
+	CASE (Bmemq):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fmemq (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bcdr:
+	CASE (Bcdr):
 	  {
 	    Lisp_Object v1;
 	    v1 = TOP;
 	    TOP = CDR (v1);
-	    break;
+	    NEXT;
 	  }
 
-	case Bvarset:
-	case Bvarset+1:
-	case Bvarset+2:
-	case Bvarset+3:
-	case Bvarset+4:
-	case Bvarset+5:
+	CASE (Bvarset):
+	CASE (Bvarset1):
+	CASE (Bvarset2):
+	CASE (Bvarset3):
+	CASE (Bvarset4):
+	CASE (Bvarset5):
 	  op -= Bvarset;
 	  goto varset;
 
-	case Bvarset+7:
+	CASE (Bvarset7):
 	  op = FETCH2;
 	  goto varset;
 
-	case Bvarset+6:
+	CASE (Bvarset6):
 	  op = FETCH;
 	varset:
 	  {
@@ -596,54 +935,54 @@ If the third argument is incorrect, Emacs may crash.  */)
 	      }
 	  }
 	  (void) POP;
-	  break;
+	  NEXT;
 
-	case Bdup:
+	CASE (Bdup):
 	  {
 	    Lisp_Object v1;
 	    v1 = TOP;
 	    PUSH (v1);
-	    break;
+	    NEXT;
 	  }
 
 	/* ------------------ */
 
-	case Bvarbind+6:
+	CASE (Bvarbind6):
 	  op = FETCH;
 	  goto varbind;
 
-	case Bvarbind+7:
+	CASE (Bvarbind7):
 	  op = FETCH2;
 	  goto varbind;
 
-	case Bvarbind:
-	case Bvarbind+1:
-	case Bvarbind+2:
-	case Bvarbind+3:
-	case Bvarbind+4:
-	case Bvarbind+5:
+	CASE (Bvarbind):
+	CASE (Bvarbind1):
+	CASE (Bvarbind2):
+	CASE (Bvarbind3):
+	CASE (Bvarbind4):
+	CASE (Bvarbind5):
 	  op -= Bvarbind;
 	varbind:
 	  /* Specbind can signal and thus GC.  */
 	  BEFORE_POTENTIAL_GC ();
 	  specbind (vectorp[op], POP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bcall+6:
+	CASE (Bcall6):
 	  op = FETCH;
 	  goto docall;
 
-	case Bcall+7:
+	CASE (Bcall7):
 	  op = FETCH2;
 	  goto docall;
 
-	case Bcall:
-	case Bcall+1:
-	case Bcall+2:
-	case Bcall+3:
-	case Bcall+4:
-	case Bcall+5:
+	CASE (Bcall):
+	CASE (Bcall1):
+	CASE (Bcall2):
+	CASE (Bcall3):
+	CASE (Bcall4):
+	CASE (Bcall5):
 	  op -= Bcall;
 	docall:
 	  {
@@ -666,47 +1005,47 @@ If the third argument is incorrect, Emacs may crash.  */)
 #endif
 	    TOP = Ffuncall (op + 1, &TOP);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bunbind+6:
+	CASE (Bunbind6):
 	  op = FETCH;
 	  goto dounbind;
 
-	case Bunbind+7:
+	CASE (Bunbind7):
 	  op = FETCH2;
 	  goto dounbind;
 
-	case Bunbind:
-	case Bunbind+1:
-	case Bunbind+2:
-	case Bunbind+3:
-	case Bunbind+4:
-	case Bunbind+5:
+	CASE (Bunbind):
+	CASE (Bunbind1):
+	CASE (Bunbind2):
+	CASE (Bunbind3):
+	CASE (Bunbind4):
+	CASE (Bunbind5):
 	  op -= Bunbind;
 	dounbind:
 	  BEFORE_POTENTIAL_GC ();
 	  unbind_to (SPECPDL_INDEX () - op, Qnil);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bunbind_all:
+	CASE (Bunbind_all):
 	  /* To unbind back to the beginning of this frame.  Not used yet,
 	     but will be needed for tail-recursion elimination.  */
 	  BEFORE_POTENTIAL_GC ();
 	  unbind_to (count, Qnil);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bgoto:
+	CASE (Bgoto):
 	  MAYBE_GC ();
 	  BYTE_CODE_QUIT;
 	  op = FETCH2;    /* pc = FETCH2 loses since FETCH2 contains pc++ */
 	  CHECK_RANGE (op);
 	  stack.pc = stack.byte_string_start + op;
-	  break;
+	  NEXT;
 
-	case Bgotoifnonnil:
+	CASE (Bgotoifnonnil):
 	  {
 	    Lisp_Object v1;
 	    MAYBE_GC ();
@@ -718,10 +1057,10 @@ If the third argument is incorrect, Emacs may crash.  */)
 		CHECK_RANGE (op);
 		stack.pc = stack.byte_string_start + op;
 	      }
-	    break;
+	    NEXT;
 	  }
 
-	case Bgotoifnilelsepop:
+	CASE (Bgotoifnilelsepop):
 	  MAYBE_GC ();
 	  op = FETCH2;
 	  if (NILP (TOP))
@@ -731,9 +1070,9 @@ If the third argument is incorrect, Emacs may crash.  */)
 	      stack.pc = stack.byte_string_start + op;
 	    }
 	  else DISCARD (1);
-	  break;
+	  NEXT;
 
-	case Bgotoifnonnilelsepop:
+	CASE (Bgotoifnonnilelsepop):
 	  MAYBE_GC ();
 	  op = FETCH2;
 	  if (!NILP (TOP))
@@ -743,15 +1082,15 @@ If the third argument is incorrect, Emacs may crash.  */)
 	      stack.pc = stack.byte_string_start + op;
 	    }
 	  else DISCARD (1);
-	  break;
+	  NEXT;
 
-	case BRgoto:
+	CASE (BRgoto):
 	  MAYBE_GC ();
 	  BYTE_CODE_QUIT;
 	  stack.pc += (int) *stack.pc - 127;
-	  break;
+	  NEXT;
 
-	case BRgotoifnil:
+	CASE (BRgotoifnil):
 	  {
 	    Lisp_Object v1;
 	    MAYBE_GC ();
@@ -762,10 +1101,10 @@ If the third argument is incorrect, Emacs may crash.  */)
 		stack.pc += (int) *stack.pc - 128;
 	      }
 	    stack.pc++;
-	    break;
+	    NEXT;
 	  }
 
-	case BRgotoifnonnil:
+	CASE (BRgotoifnonnil):
 	  {
 	    Lisp_Object v1;
 	    MAYBE_GC ();
@@ -776,10 +1115,10 @@ If the third argument is incorrect, Emacs may crash.  */)
 		stack.pc += (int) *stack.pc - 128;
 	      }
 	    stack.pc++;
-	    break;
+	    NEXT;
 	  }
 
-	case BRgotoifnilelsepop:
+	CASE (BRgotoifnilelsepop):
 	  MAYBE_GC ();
 	  op = *stack.pc++;
 	  if (NILP (TOP))
@@ -788,9 +1127,9 @@ If the third argument is incorrect, Emacs may crash.  */)
 	      stack.pc += op - 128;
 	    }
 	  else DISCARD (1);
-	  break;
+	  NEXT;
 
-	case BRgotoifnonnilelsepop:
+	CASE (BRgotoifnonnilelsepop):
 	  MAYBE_GC ();
 	  op = *stack.pc++;
 	  if (!NILP (TOP))
@@ -799,56 +1138,56 @@ If the third argument is incorrect, Emacs may crash.  */)
 	      stack.pc += op - 128;
 	    }
 	  else DISCARD (1);
-	  break;
+	  NEXT;
 
-	case Breturn:
+	CASE (Breturn):
 	  result = POP;
 	  goto exit;
 
-	case Bdiscard:
+	CASE (Bdiscard):
 	  DISCARD (1);
-	  break;
+	  NEXT;
 
-	case Bconstant2:
+	CASE (Bconstant2):
 	  PUSH (vectorp[FETCH2]);
-	  break;
+	  NEXT;
 
-	case Bsave_excursion:
+	CASE (Bsave_excursion):
 	  record_unwind_protect (save_excursion_restore,
 				 save_excursion_save ());
-	  break;
+	  NEXT;
 
-	case Bsave_current_buffer:
-	case Bsave_current_buffer_1:
+	CASE (Bsave_current_buffer):
+	CASE (Bsave_current_buffer_1):
 	  record_unwind_protect (set_buffer_if_live, Fcurrent_buffer ());
-	  break;
+	  NEXT;
 
-	case Bsave_window_excursion:
+	CASE (Bsave_window_excursion):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Fsave_window_excursion (TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bsave_restriction:
+	CASE (Bsave_restriction):
 	  record_unwind_protect (save_restriction_restore,
 				 save_restriction_save ());
-	  break;
+	  NEXT;
 
-	case Bcatch:
+	CASE (Bcatch):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = internal_catch (TOP, Feval, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bunwind_protect:
+	CASE (Bunwind_protect):
 	  record_unwind_protect (Fprogn, POP);
-	  break;
+	  NEXT;
 
-	case Bcondition_case:
+	CASE (Bcondition_case):
 	  {
 	    Lisp_Object handlers, body;
 	    handlers = POP;
@@ -856,18 +1195,18 @@ If the third argument is incorrect, Emacs may crash.  */)
 	    BEFORE_POTENTIAL_GC ();
 	    TOP = internal_lisp_condition_case (TOP, body, handlers);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Btemp_output_buffer_setup:
+	CASE (Btemp_output_buffer_setup):
 	  BEFORE_POTENTIAL_GC ();
 	  CHECK_STRING (TOP);
 	  temp_output_buffer_setup (SDATA (TOP));
 	  AFTER_POTENTIAL_GC ();
 	  TOP = Vstandard_output;
-	  break;
+	  NEXT;
 
-	case Btemp_output_buffer_show:
+	CASE (Btemp_output_buffer_show):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
@@ -877,10 +1216,10 @@ If the third argument is incorrect, Emacs may crash.  */)
 	    /* pop binding of standard-output */
 	    unbind_to (SPECPDL_INDEX () - 1, Qnil);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bnth:
+	CASE (Bnth):
 	  {
 	    Lisp_Object v1, v2;
 	    BEFORE_POTENTIAL_GC ();
@@ -894,173 +1233,173 @@ If the third argument is incorrect, Emacs may crash.  */)
 	      v1 = XCDR (v1);
 	    immediate_quit = 0;
 	    TOP = CAR (v1);
-	    break;
+	    NEXT;
 	  }
 
-	case Bsymbolp:
+	CASE (Bsymbolp):
 	  TOP = SYMBOLP (TOP) ? Qt : Qnil;
-	  break;
+	  NEXT;
 
-	case Bconsp:
+	CASE (Bconsp):
 	  TOP = CONSP (TOP) ? Qt : Qnil;
-	  break;
+	  NEXT;
 
-	case Bstringp:
+	CASE (Bstringp):
 	  TOP = STRINGP (TOP) ? Qt : Qnil;
-	  break;
+	  NEXT;
 
-	case Blistp:
+	CASE (Blistp):
 	  TOP = CONSP (TOP) || NILP (TOP) ? Qt : Qnil;
-	  break;
+	  NEXT;
 
-	case Bnot:
+	CASE (Bnot):
 	  TOP = NILP (TOP) ? Qt : Qnil;
-	  break;
+	  NEXT;
 
-	case Bcons:
+	CASE (Bcons):
 	  {
 	    Lisp_Object v1;
 	    v1 = POP;
 	    TOP = Fcons (TOP, v1);
-	    break;
+	    NEXT;
 	  }
 
-	case Blist1:
+	CASE (Blist1):
 	  TOP = Fcons (TOP, Qnil);
-	  break;
+	  NEXT;
 
-	case Blist2:
+	CASE (Blist2):
 	  {
 	    Lisp_Object v1;
 	    v1 = POP;
 	    TOP = Fcons (TOP, Fcons (v1, Qnil));
-	    break;
+	    NEXT;
 	  }
 
-	case Blist3:
+	CASE (Blist3):
 	  DISCARD (2);
 	  TOP = Flist (3, &TOP);
-	  break;
+	  NEXT;
 
-	case Blist4:
+	CASE (Blist4):
 	  DISCARD (3);
 	  TOP = Flist (4, &TOP);
-	  break;
+	  NEXT;
 
-	case BlistN:
+	CASE (BlistN):
 	  op = FETCH;
 	  DISCARD (op - 1);
 	  TOP = Flist (op, &TOP);
-	  break;
+	  NEXT;
 
-	case Blength:
+	CASE (Blength):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Flength (TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Baref:
+	CASE (Baref):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Faref (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Baset:
+	CASE (Baset):
 	  {
 	    Lisp_Object v1, v2;
 	    BEFORE_POTENTIAL_GC ();
 	    v2 = POP; v1 = POP;
 	    TOP = Faset (TOP, v1, v2);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bsymbol_value:
+	CASE (Bsymbol_value):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Fsymbol_value (TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bsymbol_function:
+	CASE (Bsymbol_function):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Fsymbol_function (TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bset:
+	CASE (Bset):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fset (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bfset:
+	CASE (Bfset):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Ffset (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bget:
+	CASE (Bget):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fget (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bsubstring:
+	CASE (Bsubstring):
 	  {
 	    Lisp_Object v1, v2;
 	    BEFORE_POTENTIAL_GC ();
 	    v2 = POP; v1 = POP;
 	    TOP = Fsubstring (TOP, v1, v2);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bconcat2:
+	CASE (Bconcat2):
 	  BEFORE_POTENTIAL_GC ();
 	  DISCARD (1);
 	  TOP = Fconcat (2, &TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bconcat3:
+	CASE (Bconcat3):
 	  BEFORE_POTENTIAL_GC ();
 	  DISCARD (2);
 	  TOP = Fconcat (3, &TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bconcat4:
+	CASE (Bconcat4):
 	  BEFORE_POTENTIAL_GC ();
 	  DISCARD (3);
 	  TOP = Fconcat (4, &TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case BconcatN:
+	CASE (BconcatN):
 	  op = FETCH;
 	  BEFORE_POTENTIAL_GC ();
 	  DISCARD (op - 1);
 	  TOP = Fconcat (op, &TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bsub1:
+	CASE (Bsub1):
 	  {
 	    Lisp_Object v1;
 	    v1 = TOP;
@@ -1075,10 +1414,10 @@ If the third argument is incorrect, Emacs may crash.  */)
 		TOP = Fsub1 (v1);
 		AFTER_POTENTIAL_GC ();
 	      }
-	    break;
+	    NEXT;
 	  }
 
-	case Badd1:
+	CASE (Badd1):
 	  {
 	    Lisp_Object v1;
 	    v1 = TOP;
@@ -1093,10 +1432,10 @@ If the third argument is incorrect, Emacs may crash.  */)
 		TOP = Fadd1 (v1);
 		AFTER_POTENTIAL_GC ();
 	      }
-	    break;
+	    NEXT;
 	  }
 
-	case Beqlsign:
+	CASE (Beqlsign):
 	  {
 	    Lisp_Object v1, v2;
 	    BEFORE_POTENTIAL_GC ();
@@ -1114,57 +1453,57 @@ If the third argument is incorrect, Emacs may crash.  */)
 	      }
 	    else
 	      TOP = (XINT (v1) == XINT (v2) ? Qt : Qnil);
-	    break;
+	    NEXT;
 	  }
 
-	case Bgtr:
+	CASE (Bgtr):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fgtr (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Blss:
+	CASE (Blss):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Flss (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bleq:
+	CASE (Bleq):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fleq (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bgeq:
+	CASE (Bgeq):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fgeq (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bdiff:
+	CASE (Bdiff):
 	  BEFORE_POTENTIAL_GC ();
 	  DISCARD (1);
 	  TOP = Fminus (2, &TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bnegate:
+	CASE (Bnegate):
 	  {
 	    Lisp_Object v1;
 	    v1 = TOP;
@@ -1179,209 +1518,209 @@ If the third argument is incorrect, Emacs may crash.  */)
 		TOP = Fminus (1, &TOP);
 		AFTER_POTENTIAL_GC ();
 	      }
-	    break;
+	    NEXT;
 	  }
 
-	case Bplus:
+	CASE (Bplus):
 	  BEFORE_POTENTIAL_GC ();
 	  DISCARD (1);
 	  TOP = Fplus (2, &TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bmax:
+	CASE (Bmax):
 	  BEFORE_POTENTIAL_GC ();
 	  DISCARD (1);
 	  TOP = Fmax (2, &TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bmin:
+	CASE (Bmin):
 	  BEFORE_POTENTIAL_GC ();
 	  DISCARD (1);
 	  TOP = Fmin (2, &TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bmult:
+	CASE (Bmult):
 	  BEFORE_POTENTIAL_GC ();
 	  DISCARD (1);
 	  TOP = Ftimes (2, &TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bquo:
+	CASE (Bquo):
 	  BEFORE_POTENTIAL_GC ();
 	  DISCARD (1);
 	  TOP = Fquo (2, &TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Brem:
+	CASE (Brem):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Frem (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bpoint:
+	CASE (Bpoint):
 	  {
 	    Lisp_Object v1;
 	    XSETFASTINT (v1, PT);
 	    PUSH (v1);
-	    break;
+	    NEXT;
 	  }
 
-	case Bgoto_char:
+	CASE (Bgoto_char):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Fgoto_char (TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Binsert:
+	CASE (Binsert):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Finsert (1, &TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case BinsertN:
+	CASE (BinsertN):
 	  op = FETCH;
 	  BEFORE_POTENTIAL_GC ();
 	  DISCARD (op - 1);
 	  TOP = Finsert (op, &TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bpoint_max:
+	CASE (Bpoint_max):
 	  {
 	    Lisp_Object v1;
 	    XSETFASTINT (v1, ZV);
 	    PUSH (v1);
-	    break;
+	    NEXT;
 	  }
 
-	case Bpoint_min:
+	CASE (Bpoint_min):
 	  {
 	    Lisp_Object v1;
 	    XSETFASTINT (v1, BEGV);
 	    PUSH (v1);
-	    break;
+	    NEXT;
 	  }
 
-	case Bchar_after:
+	CASE (Bchar_after):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Fchar_after (TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bfollowing_char:
+	CASE (Bfollowing_char):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = Ffollowing_char ();
 	    AFTER_POTENTIAL_GC ();
 	    PUSH (v1);
-	    break;
+	    NEXT;
 	  }
 
-	case Bpreceding_char:
+	CASE (Bpreceding_char):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = Fprevious_char ();
 	    AFTER_POTENTIAL_GC ();
 	    PUSH (v1);
-	    break;
+	    NEXT;
 	  }
 
-	case Bcurrent_column:
+	CASE (Bcurrent_column):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    XSETFASTINT (v1, (int) current_column ()); /* iftc */
 	    AFTER_POTENTIAL_GC ();
 	    PUSH (v1);
-	    break;
+	    NEXT;
 	  }
 
-	case Bindent_to:
+	CASE (Bindent_to):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Findent_to (TOP, Qnil);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Beolp:
+	CASE (Beolp):
 	  PUSH (Feolp ());
-	  break;
+	  NEXT;
 
-	case Beobp:
+	CASE (Beobp):
 	  PUSH (Feobp ());
-	  break;
+	  NEXT;
 
-	case Bbolp:
+	CASE (Bbolp):
 	  PUSH (Fbolp ());
-	  break;
+	  NEXT;
 
-	case Bbobp:
+	CASE (Bbobp):
 	  PUSH (Fbobp ());
-	  break;
+	  NEXT;
 
-	case Bcurrent_buffer:
+	CASE (Bcurrent_buffer):
 	  PUSH (Fcurrent_buffer ());
-	  break;
+	  NEXT;
 
-	case Bset_buffer:
+	CASE (Bset_buffer):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Fset_buffer (TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Binteractive_p:
+	CASE (Binteractive_p):
 	  PUSH (Finteractive_p ());
-	  break;
+	  NEXT;
 
-	case Bforward_char:
+	CASE (Bforward_char):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Fforward_char (TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bforward_word:
+	CASE (Bforward_word):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Fforward_word (TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bskip_chars_forward:
+	CASE (Bskip_chars_forward):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fskip_chars_forward (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bskip_chars_backward:
+	CASE (Bskip_chars_backward):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fskip_chars_backward (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bforward_line:
+	CASE (Bforward_line):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Fforward_line (TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bchar_syntax:
+	CASE (Bchar_syntax):
 	  {
 	    int c;
 
@@ -1393,51 +1732,51 @@ If the third argument is incorrect, Emacs may crash.  */)
 	      MAKE_CHAR_MULTIBYTE (c);
 	    XSETFASTINT (TOP, syntax_code_spec[(int) SYNTAX (c)]);
 	  }
-	  break;
+	  NEXT;
 
-	case Bbuffer_substring:
+	CASE (Bbuffer_substring):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fbuffer_substring (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bdelete_region:
+	CASE (Bdelete_region):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fdelete_region (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bnarrow_to_region:
+	CASE (Bnarrow_to_region):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fnarrow_to_region (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bwiden:
+	CASE (Bwiden):
 	  BEFORE_POTENTIAL_GC ();
 	  PUSH (Fwiden ());
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bend_of_line:
+	CASE (Bend_of_line):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Fend_of_line (TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bset_marker:
+	CASE (Bset_marker):
 	  {
 	    Lisp_Object v1, v2;
 	    BEFORE_POTENTIAL_GC ();
@@ -1445,72 +1784,72 @@ If the third argument is incorrect, Emacs may crash.  */)
 	    v2 = POP;
 	    TOP = Fset_marker (TOP, v2, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bmatch_beginning:
+	CASE (Bmatch_beginning):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Fmatch_beginning (TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bmatch_end:
+	CASE (Bmatch_end):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Fmatch_end (TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bupcase:
+	CASE (Bupcase):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Fupcase (TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bdowncase:
+	CASE (Bdowncase):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Fdowncase (TOP);
 	  AFTER_POTENTIAL_GC ();
-	break;
+	NEXT;
 
-	case Bstringeqlsign:
+      CASE (Bstringeqlsign):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fstring_equal (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bstringlss:
+	CASE (Bstringlss):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fstring_lessp (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bequal:
+	CASE (Bequal):
 	  {
 	    Lisp_Object v1;
 	    v1 = POP;
 	    TOP = Fequal (TOP, v1);
-	    break;
+	    NEXT;
 	  }
 
-	case Bnthcdr:
+	CASE (Bnthcdr):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fnthcdr (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Belt:
+	CASE (Belt):
 	  {
 	    Lisp_Object v1, v2;
 	    if (CONSP (TOP))
@@ -1535,104 +1874,105 @@ If the third argument is incorrect, Emacs may crash.  */)
 		TOP = Felt (TOP, v1);
 		AFTER_POTENTIAL_GC ();
 	      }
-	    break;
+	    NEXT;
 	  }
 
-	case Bmember:
+	CASE (Bmember):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fmember (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bassq:
+	CASE (Bassq):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fassq (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bnreverse:
+	CASE (Bnreverse):
 	  BEFORE_POTENTIAL_GC ();
 	  TOP = Fnreverse (TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bsetcar:
+	CASE (Bsetcar):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fsetcar (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bsetcdr:
+	CASE (Bsetcdr):
 	  {
 	    Lisp_Object v1;
 	    BEFORE_POTENTIAL_GC ();
 	    v1 = POP;
 	    TOP = Fsetcdr (TOP, v1);
 	    AFTER_POTENTIAL_GC ();
-	    break;
+	    NEXT;
 	  }
 
-	case Bcar_safe:
+	CASE (Bcar_safe):
 	  {
 	    Lisp_Object v1;
 	    v1 = TOP;
 	    TOP = CAR_SAFE (v1);
-	    break;
+	    NEXT;
 	  }
 
-	case Bcdr_safe:
+	CASE (Bcdr_safe):
 	  {
 	    Lisp_Object v1;
 	    v1 = TOP;
 	    TOP = CDR_SAFE (v1);
-	    break;
+	    NEXT;
 	  }
 
-	case Bnconc:
+	CASE (Bnconc):
 	  BEFORE_POTENTIAL_GC ();
 	  DISCARD (1);
 	  TOP = Fnconc (2, &TOP);
 	  AFTER_POTENTIAL_GC ();
-	  break;
+	  NEXT;
 
-	case Bnumberp:
+	CASE (Bnumberp):
 	  TOP = (NUMBERP (TOP) ? Qt : Qnil);
-	  break;
+	  NEXT;
 
-	case Bintegerp:
+	CASE (Bintegerp):
 	  TOP = INTEGERP (TOP) ? Qt : Qnil;
-	  break;
+	  NEXT;
 
 #ifdef BYTE_CODE_SAFE
-	case Bset_mark:
+	CASE (Bset_mark):
 	  BEFORE_POTENTIAL_GC ();
 	  error ("set-mark is an obsolete bytecode");
 	  AFTER_POTENTIAL_GC ();
-	  break;
-	case Bscan_buffer:
+	  NEXT;
+	CASE (Bscan_buffer):
 	  BEFORE_POTENTIAL_GC ();
 	  error ("scan-buffer is an obsolete bytecode");
 	  AFTER_POTENTIAL_GC ();
-	  break;
-#endif
-
-	case 0:
+	  NEXT;
+#else
+	CASE (Bset_mark):
+	CASE (Bscan_buffer):
 	  abort ();
+#endif
 
-	case 255:
-	default:
+	CASE_DEFAULT
+	CASE (Bconstant):
 #ifdef BYTE_CODE_SAFE
 	  if (op < Bconstant)
 	    {
@@ -1646,6 +1986,10 @@ If the third argument is incorrect, Emacs may crash.  */)
 #else
 	  PUSH (vectorp[op - Bconstant]);
 #endif
+	  NEXT;
+
+	CASE_ABORT:
+	  abort ();
 	}
     }