bytecode.c 32.7 KB
Newer Older
Jim Blandy's avatar
Jim Blandy committed
1
/* Execution of byte code produced by bytecomp.el.
Paul Eggert's avatar
Paul Eggert committed
2
   Copyright (C) 1985-1988, 1993, 2000-2016 Free Software Foundation,
3
   Inc.
Jim Blandy's avatar
Jim Blandy committed
4 5 6

This file is part of GNU Emacs.

7
GNU Emacs is free software: you can redistribute it and/or modify
Jim Blandy's avatar
Jim Blandy committed
8
it under the terms of the GNU General Public License as published by
9 10
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
Jim Blandy's avatar
Jim Blandy committed
11 12 13 14 15 16 17

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
18
along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
Jim Blandy's avatar
Jim Blandy committed
19

20
#include <config.h>
21

Jim Blandy's avatar
Jim Blandy committed
22
#include "lisp.h"
Paul Eggert's avatar
Paul Eggert committed
23
#include "blockinput.h"
24
#include "character.h"
25
#include "buffer.h"
Paul Eggert's avatar
Paul Eggert committed
26
#include "keyboard.h"
Jim Blandy's avatar
Jim Blandy committed
27
#include "syntax.h"
Stefan Monnier's avatar
Stefan Monnier committed
28
#include "window.h"
Jim Blandy's avatar
Jim Blandy committed
29

30 31 32 33 34
/* Work around GCC bug 54561.  */
#if GNUC_PREREQ (4, 3, 0)
# pragma GCC diagnostic ignored "-Wclobbered"
#endif

Paul Eggert's avatar
Paul Eggert committed
35 36 37 38 39 40 41 42
/* Define BYTE_CODE_SAFE true to enable some minor sanity checking,
   useful for debugging the byte compiler.  It defaults to false.  */

#ifndef BYTE_CODE_SAFE
# define BYTE_CODE_SAFE false
#endif

/* Define BYTE_CODE_METER to generate a byte-op usage histogram.  */
43
/* #define BYTE_CODE_METER */
Jim Blandy's avatar
Jim Blandy committed
44

Tom Tromey's avatar
Tom Tromey committed
45 46 47 48
/* If BYTE_CODE_THREADED is defined, then the interpreter will be
   indirect threaded, using GCC's computed goto extension.  This code,
   as currently implemented, is incompatible with BYTE_CODE_SAFE and
   BYTE_CODE_METER.  */
Paul Eggert's avatar
Paul Eggert committed
49
#if (defined __GNUC__ && !defined __STRICT_ANSI__ \
Paul Eggert's avatar
Paul Eggert committed
50
     && !BYTE_CODE_SAFE && !defined BYTE_CODE_METER)
Tom Tromey's avatar
Tom Tromey committed
51 52 53
#define BYTE_CODE_THREADED
#endif

Jim Blandy's avatar
Jim Blandy committed
54 55 56

#ifdef BYTE_CODE_METER

57 58
#define METER_2(code1, code2) \
  (*aref_addr (AREF (Vbyte_code_meter, code1), code2))
59
#define METER_1(code) METER_2 (0, code)
60

61 62 63 64
#define METER_CODE(last_code, this_code)				\
{									\
  if (byte_metering_on)							\
    {									\
65 66 67
      if (XFASTINT (METER_1 (this_code)) < MOST_POSITIVE_FIXNUM)	\
        XSETFASTINT (METER_1 (this_code),				\
		     XFASTINT (METER_1 (this_code)) + 1);		\
68
      if (last_code							\
69 70 71 72
	  && (XFASTINT (METER_2 (last_code, this_code))			\
	      < MOST_POSITIVE_FIXNUM))					\
        XSETFASTINT (METER_2 (last_code, this_code),			\
		     XFASTINT (METER_2 (last_code, this_code)) + 1);	\
73
    }									\
74
}
Jim Blandy's avatar
Jim Blandy committed
75

76
#endif /* BYTE_CODE_METER */
Jim Blandy's avatar
Jim Blandy committed
77 78 79 80


/*  Byte codes: */

Tom Tromey's avatar
Tom Tromey committed
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
#define BYTE_CODES							\
DEFINE (Bstack_ref, 0) /* Actually, Bstack_ref+0 is not implemented: use dup.  */ \
DEFINE (Bstack_ref1, 1)							\
DEFINE (Bstack_ref2, 2)							\
DEFINE (Bstack_ref3, 3)							\
DEFINE (Bstack_ref4, 4)							\
DEFINE (Bstack_ref5, 5)							\
DEFINE (Bstack_ref6, 6)							\
DEFINE (Bstack_ref7, 7)							\
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)							\
									\
131 132 133 134
DEFINE (Bpophandler, 060)						\
DEFINE (Bpushconditioncase, 061)					\
DEFINE (Bpushcatch, 062)						\
									\
Tom Tromey's avatar
Tom Tromey committed
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
DEFINE (Bnth, 070)							\
DEFINE (Bsymbolp, 071)							\
DEFINE (Bconsp, 072)							\
DEFINE (Bstringp, 073)							\
DEFINE (Blistp, 074)							\
DEFINE (Beq, 075)							\
DEFINE (Bmemq, 076)							\
DEFINE (Bnot, 077)							\
DEFINE (Bcar, 0100)							\
DEFINE (Bcdr, 0101)							\
DEFINE (Bcons, 0102)							\
DEFINE (Blist1, 0103)							\
DEFINE (Blist2, 0104)							\
DEFINE (Blist3, 0105)							\
DEFINE (Blist4, 0106)							\
DEFINE (Blength, 0107)							\
DEFINE (Baref, 0110)							\
DEFINE (Baset, 0111)							\
DEFINE (Bsymbol_value, 0112)						\
DEFINE (Bsymbol_function, 0113)						\
DEFINE (Bset, 0114)							\
DEFINE (Bfset, 0115)							\
DEFINE (Bget, 0116)							\
DEFINE (Bsubstring, 0117)						\
DEFINE (Bconcat2, 0120)							\
DEFINE (Bconcat3, 0121)							\
DEFINE (Bconcat4, 0122)							\
DEFINE (Bsub1, 0123)							\
DEFINE (Badd1, 0124)							\
DEFINE (Beqlsign, 0125)							\
DEFINE (Bgtr, 0126)							\
DEFINE (Blss, 0127)							\
DEFINE (Bleq, 0130)							\
DEFINE (Bgeq, 0131)							\
DEFINE (Bdiff, 0132)							\
DEFINE (Bnegate, 0133)							\
DEFINE (Bplus, 0134)							\
DEFINE (Bmax, 0135)							\
DEFINE (Bmin, 0136)							\
DEFINE (Bmult, 0137)							\
									\
DEFINE (Bpoint, 0140)							\
/* Was Bmark in v17.  */						\
DEFINE (Bsave_current_buffer, 0141) /* Obsolete.  */			\
DEFINE (Bgoto_char, 0142)						\
DEFINE (Binsert, 0143)							\
DEFINE (Bpoint_max, 0144)						\
DEFINE (Bpoint_min, 0145)						\
DEFINE (Bchar_after, 0146)						\
DEFINE (Bfollowing_char, 0147)						\
DEFINE (Bpreceding_char, 0150)						\
DEFINE (Bcurrent_column, 0151)						\
DEFINE (Bindent_to, 0152)						\
DEFINE (Beolp, 0154)							\
DEFINE (Beobp, 0155)							\
DEFINE (Bbolp, 0156)							\
DEFINE (Bbobp, 0157)							\
DEFINE (Bcurrent_buffer, 0160)						\
DEFINE (Bset_buffer, 0161)						\
DEFINE (Bsave_current_buffer_1, 0162) /* Replacing Bsave_current_buffer.  */ \
DEFINE (Binteractive_p, 0164) /* Obsolete since Emacs-24.1.  */		\
									\
DEFINE (Bforward_char, 0165)						\
DEFINE (Bforward_word, 0166)						\
DEFINE (Bskip_chars_forward, 0167)					\
DEFINE (Bskip_chars_backward, 0170)					\
DEFINE (Bforward_line, 0171)						\
DEFINE (Bchar_syntax, 0172)						\
DEFINE (Bbuffer_substring, 0173)					\
DEFINE (Bdelete_region, 0174)						\
DEFINE (Bnarrow_to_region, 0175)					\
DEFINE (Bwiden, 0176)							\
DEFINE (Bend_of_line, 0177)						\
									\
DEFINE (Bconstant2, 0201)						\
DEFINE (Bgoto, 0202)							\
DEFINE (Bgotoifnil, 0203)						\
DEFINE (Bgotoifnonnil, 0204)						\
DEFINE (Bgotoifnilelsepop, 0205)					\
DEFINE (Bgotoifnonnilelsepop, 0206)					\
DEFINE (Breturn, 0207)							\
DEFINE (Bdiscard, 0210)							\
DEFINE (Bdup, 0211)							\
									\
DEFINE (Bsave_excursion, 0212)						\
DEFINE (Bsave_window_excursion, 0213) /* Obsolete since Emacs-24.1.  */	\
DEFINE (Bsave_restriction, 0214)					\
DEFINE (Bcatch, 0215)							\
									\
DEFINE (Bunwind_protect, 0216)						\
DEFINE (Bcondition_case, 0217)						\
DEFINE (Btemp_output_buffer_setup, 0220) /* Obsolete since Emacs-24.1.  */ \
DEFINE (Btemp_output_buffer_show, 0221)  /* Obsolete since Emacs-24.1.  */ \
									\
DEFINE (Bunbind_all, 0222)	/* Obsolete.  Never used.  */		\
									\
DEFINE (Bset_marker, 0223)						\
DEFINE (Bmatch_beginning, 0224)						\
DEFINE (Bmatch_end, 0225)						\
DEFINE (Bupcase, 0226)							\
DEFINE (Bdowncase, 0227)						\
									\
DEFINE (Bstringeqlsign, 0230)						\
DEFINE (Bstringlss, 0231)						\
DEFINE (Bequal, 0232)							\
DEFINE (Bnthcdr, 0233)							\
DEFINE (Belt, 0234)							\
DEFINE (Bmember, 0235)							\
DEFINE (Bassq, 0236)							\
DEFINE (Bnreverse, 0237)						\
DEFINE (Bsetcar, 0240)							\
DEFINE (Bsetcdr, 0241)							\
DEFINE (Bcar_safe, 0242)						\
DEFINE (Bcdr_safe, 0243)						\
DEFINE (Bnconc, 0244)							\
DEFINE (Bquo, 0245)							\
DEFINE (Brem, 0246)							\
DEFINE (Bnumberp, 0247)							\
DEFINE (Bintegerp, 0250)						\
									\
DEFINE (BRgoto, 0252)							\
DEFINE (BRgotoifnil, 0253)						\
DEFINE (BRgotoifnonnil, 0254)						\
DEFINE (BRgotoifnilelsepop, 0255)					\
DEFINE (BRgotoifnonnilelsepop, 0256)					\
									\
DEFINE (BlistN, 0257)							\
DEFINE (BconcatN, 0260)							\
DEFINE (BinsertN, 0261)							\
									\
/* Bstack_ref is code 0.  */						\
DEFINE (Bstack_set,  0262)						\
DEFINE (Bstack_set2, 0263)						\
DEFINE (BdiscardN,   0266)						\
									\
DEFINE (Bconstant, 0300)

enum byte_code_op
{
#define DEFINE(name, value) name = value,
    BYTE_CODES
#undef DEFINE

Paul Eggert's avatar
Paul Eggert committed
278
#if BYTE_CODE_SAFE
Tom Tromey's avatar
Tom Tromey committed
279
    Bscan_buffer = 0153, /* No longer generated as of v18.  */
Paul Eggert's avatar
Paul Eggert committed
280
    Bset_mark = 0163, /* this loser is no longer generated as of v18 */
281
#endif
Tom Tromey's avatar
Tom Tromey committed
282
};
Jim Blandy's avatar
Jim Blandy committed
283

284
/* Fetch the next byte from the bytecode stream.  */
Jim Blandy's avatar
Jim Blandy committed
285

286
#define FETCH (*pc++)
Jim Blandy's avatar
Jim Blandy committed
287

288
/* Fetch two bytes from the bytecode stream and make a 16-bit number
289
   out of them.  */
Jim Blandy's avatar
Jim Blandy committed
290 291 292

#define FETCH2 (op = FETCH, op + (FETCH << 8))

293 294
/* Push X onto the execution stack.  The expression X should not
   contain TOP, to avoid competing side effects.  */
Gerd Moellmann's avatar
Gerd Moellmann committed
295

296
#define PUSH(x) (*++top = (x))
Jim Blandy's avatar
Jim Blandy committed
297 298 299

/* Pop a value off the execution stack.  */

Gerd Moellmann's avatar
Gerd Moellmann committed
300
#define POP (*top--)
Jim Blandy's avatar
Jim Blandy committed
301 302 303

/* Discard n values from the execution stack.  */

Gerd Moellmann's avatar
Gerd Moellmann committed
304 305 306
#define DISCARD(n) (top -= (n))

/* Get the value which is at the top of the execution stack, but don't
307
   pop it.  */
Gerd Moellmann's avatar
Gerd Moellmann committed
308 309

#define TOP (*top)
Jim Blandy's avatar
Jim Blandy committed
310 311

DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0,
312 313 314 315 316
       doc: /* Function used internally in byte-compiled code.
The first argument, BYTESTR, is a string of byte code;
the second, VECTOR, a vector of constants;
the third, MAXDEPTH, the maximum stack depth used in this function.
If the third argument is incorrect, Emacs may crash.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
317
  (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth)
318
{
319
  return exec_byte_code (bytestr, vector, maxdepth, Qnil, 0, NULL);
320 321
}

322 323 324 325 326 327
static void
bcall0 (Lisp_Object f)
{
  Ffuncall (1, &f);
}

328 329 330 331 332 333 334 335 336
/* Execute the byte-code in BYTESTR.  VECTOR is the constant vector, and
   MAXDEPTH is the maximum stack depth used (if MAXDEPTH is incorrect,
   emacs may crash!).  If ARGS_TEMPLATE is non-nil, it should be a lisp
   argument list (including &rest, &optional, etc.), and ARGS, of size
   NARGS, should be a vector of the actual arguments.  The arguments in
   ARGS are pushed on the stack according to ARGS_TEMPLATE before
   executing BYTESTR.  */

Lisp_Object
Stefan Monnier's avatar
Stefan Monnier committed
337
exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
338
		Lisp_Object args_template, ptrdiff_t nargs, Lisp_Object *args)
Jim Blandy's avatar
Jim Blandy committed
339 340
{
#ifdef BYTE_CODE_METER
341
  int volatile this_op = 0;
Jim Blandy's avatar
Jim Blandy committed
342 343
#endif

344
  CHECK_STRING (bytestr);
Kim F. Storm's avatar
Kim F. Storm committed
345
  CHECK_VECTOR (vector);
346
  CHECK_NATNUM (maxdepth);
Jim Blandy's avatar
Jim Blandy committed
347

348
  ptrdiff_t const_length = ASIZE (vector);
349

350 351 352 353 354
  if (STRING_MULTIBYTE (bytestr))
    /* BYTESTR must have been produced by Emacs 20.2 or the earlier
       because they produced a raw 8-bit string for byte-code and now
       such a byte-code string is loaded as multibyte while raw 8-bit
       characters converted to multibyte form.  Thus, now we must
355
       convert them back to the originally intended unibyte form.  */
356
    bytestr = Fstring_as_unibyte (bytestr);
357

358 359
  ptrdiff_t bytestr_length = SBYTES (bytestr);
  Lisp_Object *vectorp = XVECTOR (vector)->contents;
360

361
  unsigned char quitcounter = 1;
362
  EMACS_INT stack_items = XFASTINT (maxdepth) + 1;
363
  USE_SAFE_ALLOCA;
364
  Lisp_Object *stack_base;
365
  SAFE_ALLOCA_LISP_EXTRA (stack_base, stack_items, bytestr_length);
Paul Eggert's avatar
Paul Eggert committed
366
  Lisp_Object *stack_lim = stack_base + stack_items;
367
  Lisp_Object *top = stack_base;
368 369 370 371
  memcpy (stack_lim, SDATA (bytestr), bytestr_length);
  void *void_stack_lim = stack_lim;
  unsigned char const *bytestr_data = void_stack_lim;
  unsigned char const *pc = bytestr_data;
372
  ptrdiff_t count = SPECPDL_INDEX ();
Jim Blandy's avatar
Jim Blandy committed
373

374
  if (!NILP (args_template))
375
    {
376
      eassert (INTEGERP (args_template));
377
      ptrdiff_t at = XINT (args_template);
378
      bool rest = (at & 128) != 0;
379
      int mandatory = at & 127;
380
      ptrdiff_t nonrest = at >> 8;
381 382
      ptrdiff_t maxargs = rest ? PTRDIFF_MAX : nonrest;
      if (! (mandatory <= nargs && nargs <= maxargs))
383
	Fsignal (Qwrong_number_of_arguments,
384 385
		 list2 (Fcons (make_number (mandatory), make_number (nonrest)),
			make_number (nargs)));
386 387 388 389 390 391 392 393
      ptrdiff_t pushedargs = min (nonrest, nargs);
      for (ptrdiff_t i = 0; i < pushedargs; i++, args++)
	PUSH (*args);
      if (nonrest < nargs)
	PUSH (Flist (nargs - nonrest, args));
      else
	for (ptrdiff_t i = nargs - rest; i < nonrest; i++)
	  PUSH (Qnil);
394 395
    }

396
  while (true)
Jim Blandy's avatar
Jim Blandy committed
397
    {
398 399 400
      int op;
      enum handlertype type;

Paul Eggert's avatar
Paul Eggert committed
401
      if (BYTE_CODE_SAFE && ! (stack_base <= top && top < stack_lim))
402
	emacs_abort ();
Jim Blandy's avatar
Jim Blandy committed
403 404

#ifdef BYTE_CODE_METER
405
      int prev_op = this_op;
Jim Blandy's avatar
Jim Blandy committed
406 407
      this_op = op = FETCH;
      METER_CODE (prev_op, op);
408
#elif !defined BYTE_CODE_THREADED
409
      op = FETCH;
Tom Tromey's avatar
Tom Tromey committed
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451
#endif

      /* The interpreter can be compiled one of two ways: as an
	 ordinary switch-based interpreter, or as a threaded
	 interpreter.  The threaded interpreter relies on GCC's
	 computed goto extension, so it is not available everywhere.
	 Threading provides a performance boost.  These macros are how
	 we allow the code to be compiled both ways.  */
#ifdef BYTE_CODE_THREADED
      /* The CASE macro introduces an instruction's body.  It is
	 either a label or a case label.  */
#define CASE(OP) insn_ ## OP
      /* NEXT is invoked at the end of an instruction to go to the
	 next instruction.  It is either a computed goto, or a
	 plain break.  */
#define NEXT goto *(targets[op = FETCH])
      /* FIRST is like NEXT, but is only used at the start of the
	 interpreter body.  In the switch-based interpreter it is the
	 switch, so the threaded definition must include a semicolon.  */
#define FIRST NEXT;
      /* Most cases are labeled with the CASE macro, above.
	 CASE_DEFAULT is one exception; it is used if the interpreter
	 being built requires a default case.  The threaded
	 interpreter does not, because the dispatch table is
	 completely filled.  */
#define CASE_DEFAULT
      /* This introduces an instruction that is known to call abort.  */
#define CASE_ABORT CASE (Bstack_ref): CASE (default)
#else
      /* See above for the meaning of the various defines.  */
#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

      /* A convenience define that saves us a lot of typing and makes
	 the table clearer.  */
#define LABEL(OP) [OP] = &&insn_ ## OP
Jim Blandy's avatar
Jim Blandy committed
452

453
#if GNUC_PREREQ (4, 6, 0)
454 455
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Woverride-init"
456 457 458
#elif defined __clang__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Winitializer-overrides"
459 460
#endif

Tom Tromey's avatar
Tom Tromey committed
461 462
      /* This is the dispatch table for the threaded interpreter.  */
      static const void *const targets[256] =
463
	{
Tom Tromey's avatar
Tom Tromey committed
464 465 466 467 468 469 470
	  [0 ... (Bconstant - 1)] = &&insn_default,
	  [Bconstant ... 255] = &&insn_Bconstant,

#define DEFINE(name, value) LABEL (name) ,
	  BYTE_CODES
#undef DEFINE
	};
471

472
#if GNUC_PREREQ (4, 6, 0) || defined __clang__
473 474 475
# pragma GCC diagnostic pop
#endif

Tom Tromey's avatar
Tom Tromey committed
476 477 478 479 480 481
#endif


      FIRST
	{
	CASE (Bvarref7):
Jim Blandy's avatar
Jim Blandy committed
482 483 484
	  op = FETCH2;
	  goto varref;

Tom Tromey's avatar
Tom Tromey committed
485 486 487 488 489 490
	CASE (Bvarref):
	CASE (Bvarref1):
	CASE (Bvarref2):
	CASE (Bvarref3):
	CASE (Bvarref4):
	CASE (Bvarref5):
491
	  op -= Bvarref;
492 493 494 495
	  goto varref;

	/* This seems to be the most frequently executed byte-code
	   among the Bvarref's, so avoid a goto here.  */
Tom Tromey's avatar
Tom Tromey committed
496
	CASE (Bvarref6):
497
	  op = FETCH;
Jim Blandy's avatar
Jim Blandy committed
498
	varref:
499
	  {
500 501 502 503 504
	    Lisp_Object v1 = vectorp[op], v2;
	    if (!SYMBOLP (v1)
		|| XSYMBOL (v1)->redirect != SYMBOL_PLAINVAL
		|| (v2 = SYMBOL_VAL (XSYMBOL (v1)), EQ (v2, Qunbound)))
	      v2 = Fsymbol_value (v1);
505
	    PUSH (v2);
Tom Tromey's avatar
Tom Tromey committed
506
	    NEXT;
507 508
	  }

Tom Tromey's avatar
Tom Tromey committed
509
	CASE (Bgotoifnil):
510
	  {
511
	    Lisp_Object v1 = POP;
512 513
	    op = FETCH2;
	    if (NILP (v1))
514
	      goto op_branch;
Tom Tromey's avatar
Tom Tromey committed
515
	    NEXT;
516
	  }
Jim Blandy's avatar
Jim Blandy committed
517

Tom Tromey's avatar
Tom Tromey committed
518
	CASE (Bcar):
519 520 521 522 523
	  if (CONSP (TOP))
	    TOP = XCAR (TOP);
	  else if (!NILP (TOP))
	    wrong_type_argument (Qlistp, TOP);
	  NEXT;
524

Tom Tromey's avatar
Tom Tromey committed
525
	CASE (Beq):
526
	  {
527
	    Lisp_Object v1 = POP;
528
	    TOP = EQ (v1, TOP) ? Qt : Qnil;
Tom Tromey's avatar
Tom Tromey committed
529
	    NEXT;
530 531
	  }

Tom Tromey's avatar
Tom Tromey committed
532
	CASE (Bmemq):
533
	  {
534
	    Lisp_Object v1 = POP;
535
	    TOP = Fmemq (TOP, v1);
Tom Tromey's avatar
Tom Tromey committed
536
	    NEXT;
537 538
	  }

Tom Tromey's avatar
Tom Tromey committed
539
	CASE (Bcdr):
540
	  {
541 542 543 544
	    if (CONSP (TOP))
	      TOP = XCDR (TOP);
	    else if (!NILP (TOP))
	      wrong_type_argument (Qlistp, TOP);
Tom Tromey's avatar
Tom Tromey committed
545
	    NEXT;
546
	  }
Jim Blandy's avatar
Jim Blandy committed
547

Tom Tromey's avatar
Tom Tromey committed
548 549 550 551 552 553
	CASE (Bvarset):
	CASE (Bvarset1):
	CASE (Bvarset2):
	CASE (Bvarset3):
	CASE (Bvarset4):
	CASE (Bvarset5):
554
	  op -= Bvarset;
Jim Blandy's avatar
Jim Blandy committed
555 556
	  goto varset;

Tom Tromey's avatar
Tom Tromey committed
557
	CASE (Bvarset7):
558
	  op = FETCH2;
559 560
	  goto varset;

Tom Tromey's avatar
Tom Tromey committed
561
	CASE (Bvarset6):
562
	  op = FETCH;
Jim Blandy's avatar
Jim Blandy committed
563
	varset:
564
	  {
565 566
	    Lisp_Object sym = vectorp[op];
	    Lisp_Object val = POP;
567 568 569 570

	    /* Inline the most common case.  */
	    if (SYMBOLP (sym)
		&& !EQ (val, Qunbound)
571 572
		&& !XSYMBOL (sym)->redirect
		&& !SYMBOL_CONSTANT_P (sym))
573
	      SET_SYMBOL_VAL (XSYMBOL (sym), val);
574
	    else
575
	      set_internal (sym, val, Qnil, false);
576
	  }
Tom Tromey's avatar
Tom Tromey committed
577
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
578

Tom Tromey's avatar
Tom Tromey committed
579
	CASE (Bdup):
580
	  {
581
	    Lisp_Object v1 = TOP;
582
	    PUSH (v1);
Tom Tromey's avatar
Tom Tromey committed
583
	    NEXT;
584 585 586 587
	  }

	/* ------------------ */

Tom Tromey's avatar
Tom Tromey committed
588
	CASE (Bvarbind6):
Jim Blandy's avatar
Jim Blandy committed
589 590 591
	  op = FETCH;
	  goto varbind;

Tom Tromey's avatar
Tom Tromey committed
592
	CASE (Bvarbind7):
Jim Blandy's avatar
Jim Blandy committed
593 594 595
	  op = FETCH2;
	  goto varbind;

Tom Tromey's avatar
Tom Tromey committed
596 597 598 599 600 601
	CASE (Bvarbind):
	CASE (Bvarbind1):
	CASE (Bvarbind2):
	CASE (Bvarbind3):
	CASE (Bvarbind4):
	CASE (Bvarbind5):
Jim Blandy's avatar
Jim Blandy committed
602 603
	  op -= Bvarbind;
	varbind:
604
	  /* Specbind can signal and thus GC.  */
Jim Blandy's avatar
Jim Blandy committed
605
	  specbind (vectorp[op], POP);
Tom Tromey's avatar
Tom Tromey committed
606
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
607

Tom Tromey's avatar
Tom Tromey committed
608
	CASE (Bcall6):
Jim Blandy's avatar
Jim Blandy committed
609 610 611
	  op = FETCH;
	  goto docall;

Tom Tromey's avatar
Tom Tromey committed
612
	CASE (Bcall7):
Jim Blandy's avatar
Jim Blandy committed
613 614 615
	  op = FETCH2;
	  goto docall;

Tom Tromey's avatar
Tom Tromey committed
616 617 618 619 620 621
	CASE (Bcall):
	CASE (Bcall1):
	CASE (Bcall2):
	CASE (Bcall3):
	CASE (Bcall4):
	CASE (Bcall5):
Jim Blandy's avatar
Jim Blandy committed
622 623
	  op -= Bcall;
	docall:
624 625
	  {
	    DISCARD (op);
626
#ifdef BYTE_CODE_METER
627 628
	    if (byte_metering_on && SYMBOLP (TOP))
	      {
629 630
		Lisp_Object v1 = TOP;
		Lisp_Object v2 = Fget (v1, Qbyte_code_meter);
631
		if (INTEGERP (v2)
632
		    && XINT (v2) < MOST_POSITIVE_FIXNUM)
633 634 635 636 637
		  {
		    XSETINT (v2, XINT (v2) + 1);
		    Fput (v1, Qbyte_code_meter, v2);
		  }
	      }
638
#endif
639
	    TOP = Ffuncall (op + 1, &TOP);
Tom Tromey's avatar
Tom Tromey committed
640
	    NEXT;
641
	  }
Jim Blandy's avatar
Jim Blandy committed
642

Tom Tromey's avatar
Tom Tromey committed
643
	CASE (Bunbind6):
Jim Blandy's avatar
Jim Blandy committed
644 645 646
	  op = FETCH;
	  goto dounbind;

Tom Tromey's avatar
Tom Tromey committed
647
	CASE (Bunbind7):
Jim Blandy's avatar
Jim Blandy committed
648 649 650
	  op = FETCH2;
	  goto dounbind;

Tom Tromey's avatar
Tom Tromey committed
651 652 653 654 655 656
	CASE (Bunbind):
	CASE (Bunbind1):
	CASE (Bunbind2):
	CASE (Bunbind3):
	CASE (Bunbind4):
	CASE (Bunbind5):
Jim Blandy's avatar
Jim Blandy committed
657 658
	  op -= Bunbind;
	dounbind:
Juanma Barranquero's avatar
Juanma Barranquero committed
659
	  unbind_to (SPECPDL_INDEX () - op, Qnil);
Tom Tromey's avatar
Tom Tromey committed
660
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
661

Tom Tromey's avatar
Tom Tromey committed
662
	CASE (Bunbind_all):	/* Obsolete.  Never used.  */
Jim Blandy's avatar
Jim Blandy committed
663
	  /* To unbind back to the beginning of this frame.  Not used yet,
664
	     but will be needed for tail-recursion elimination.  */
Jim Blandy's avatar
Jim Blandy committed
665
	  unbind_to (count, Qnil);
Tom Tromey's avatar
Tom Tromey committed
666
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
667

Tom Tromey's avatar
Tom Tromey committed
668
	CASE (Bgoto):
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684
	  op = FETCH2;
	op_branch:
	  op -= pc - bytestr_data;
	op_relative_branch:
	  if (BYTE_CODE_SAFE
	      && ! (bytestr_data - pc <= op
		    && op < bytestr_data + bytestr_length - pc))
	    emacs_abort ();
	  quitcounter += op < 0;
	  if (!quitcounter)
	    {
	      quitcounter = 1;
	      maybe_gc ();
	      QUIT;
	    }
	  pc += op;
Tom Tromey's avatar
Tom Tromey committed
685
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
686

Tom Tromey's avatar
Tom Tromey committed
687
	CASE (Bgotoifnonnil):
688 689 690 691
	  op = FETCH2;
	  if (!NILP (POP))
	    goto op_branch;
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
692

Tom Tromey's avatar
Tom Tromey committed
693
	CASE (Bgotoifnilelsepop):
Jim Blandy's avatar
Jim Blandy committed
694
	  op = FETCH2;
Joseph Arceneaux's avatar
Joseph Arceneaux committed
695
	  if (NILP (TOP))
696 697
	    goto op_branch;
	  DISCARD (1);
Tom Tromey's avatar
Tom Tromey committed
698
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
699

Tom Tromey's avatar
Tom Tromey committed
700
	CASE (Bgotoifnonnilelsepop):
Jim Blandy's avatar
Jim Blandy committed
701
	  op = FETCH2;
Joseph Arceneaux's avatar
Joseph Arceneaux committed
702
	  if (!NILP (TOP))
703 704
	    goto op_branch;
	  DISCARD (1);
Tom Tromey's avatar
Tom Tromey committed
705
	  NEXT;
706

Tom Tromey's avatar
Tom Tromey committed
707
	CASE (BRgoto):
708 709
	  op = FETCH - 128;
	  goto op_relative_branch;
710

Tom Tromey's avatar
Tom Tromey committed
711
	CASE (BRgotoifnil):
712 713 714 715
	  op = FETCH - 128;
	  if (NILP (POP))
	    goto op_relative_branch;
	  NEXT;
716

Tom Tromey's avatar
Tom Tromey committed
717
	CASE (BRgotoifnonnil):
718 719 720 721
	  op = FETCH - 128;
	  if (!NILP (POP))
	    goto op_relative_branch;
	  NEXT;
722

Tom Tromey's avatar
Tom Tromey committed
723
	CASE (BRgotoifnilelsepop):
724
	  op = FETCH - 128;
725
	  if (NILP (TOP))
726 727
	    goto op_relative_branch;
	  DISCARD (1);
Tom Tromey's avatar
Tom Tromey committed
728
	  NEXT;
729

Tom Tromey's avatar
Tom Tromey committed
730
	CASE (BRgotoifnonnilelsepop):
731
	  op = FETCH - 128;
732
	  if (!NILP (TOP))
733 734
	    goto op_relative_branch;
	  DISCARD (1);
Tom Tromey's avatar
Tom Tromey committed
735
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
736

Tom Tromey's avatar
Tom Tromey committed
737
	CASE (Breturn):
Jim Blandy's avatar
Jim Blandy committed
738 739
	  goto exit;

Tom Tromey's avatar
Tom Tromey committed
740
	CASE (Bdiscard):
741
	  DISCARD (1);
Tom Tromey's avatar
Tom Tromey committed
742
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
743

Tom Tromey's avatar
Tom Tromey committed
744
	CASE (Bconstant2):
Jim Blandy's avatar
Jim Blandy committed
745
	  PUSH (vectorp[FETCH2]);
Tom Tromey's avatar
Tom Tromey committed
746
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
747

Tom Tromey's avatar
Tom Tromey committed
748
	CASE (Bsave_excursion):
749 750
	  record_unwind_protect (save_excursion_restore,
				 save_excursion_save ());
Tom Tromey's avatar
Tom Tromey committed
751
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
752

Tom Tromey's avatar
Tom Tromey committed
753 754
	CASE (Bsave_current_buffer): /* Obsolete since ??.  */
	CASE (Bsave_current_buffer_1):
755
	  record_unwind_current_buffer ();
Tom Tromey's avatar
Tom Tromey committed
756
	  NEXT;
757

Tom Tromey's avatar
Tom Tromey committed
758
	CASE (Bsave_window_excursion): /* Obsolete since 24.1.  */
759
	  {
760 761
	    ptrdiff_t count1 = SPECPDL_INDEX ();
	    record_unwind_protect (restore_window_configuration,
762 763
				   Fcurrent_window_configuration (Qnil));
	    TOP = Fprogn (TOP);
764
	    unbind_to (count1, TOP);
Tom Tromey's avatar
Tom Tromey committed
765
	    NEXT;
766
	  }
Jim Blandy's avatar
Jim Blandy committed
767

Tom Tromey's avatar
Tom Tromey committed
768
	CASE (Bsave_restriction):
769 770
	  record_unwind_protect (save_restriction_restore,
				 save_restriction_save ());
Tom Tromey's avatar
Tom Tromey committed
771
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
772

773
	CASE (Bcatch):		/* Obsolete since 24.4.  */
774
	  {
775
	    Lisp_Object v1 = POP;
776
	    TOP = internal_catch (TOP, eval_sub, v1);
Tom Tromey's avatar
Tom Tromey committed
777
	    NEXT;
778
	  }
Jim Blandy's avatar
Jim Blandy committed
779

780 781 782 783
	CASE (Bpushcatch):	/* New in 24.4.  */
	  type = CATCHER;
	  goto pushhandler;
	CASE (Bpushconditioncase): /* New in 24.4.  */
784 785
	  type = CONDITION_CASE;
	pushhandler:
786
	  {
787 788
	    struct handler *c = push_handler (POP, type);
	    c->bytecode_dest = FETCH2;
789
	    c->bytecode_top = top;
790

791 792 793 794
	    if (sys_setjmp (c->jmp))
	      {
		struct handler *c = handlerlist;
		top = c->bytecode_top;
795
		op = c->bytecode_dest;
796 797
		handlerlist = c->next;
		PUSH (c->val);
798
		goto op_branch;
799
	      }
800

801 802 803 804
	    NEXT;
	  }

	CASE (Bpophandler):	/* New in 24.4.  */
805 806
	  handlerlist = handlerlist->next;
	  NEXT;
807

Tom Tromey's avatar
Tom Tromey committed
808
	CASE (Bunwind_protect):	/* FIXME: avoid closure for lexbind.  */
809 810 811
	  {
	    Lisp_Object handler = POP;
	    /* Support for a function here is new in 24.4.  */
812 813
	    record_unwind_protect ((NILP (Ffunctionp (handler))
				    ? unwind_body : bcall0),
814 815 816
				   handler);
	    NEXT;
	  }
Jim Blandy's avatar
Jim Blandy committed
817

818
	CASE (Bcondition_case):		/* Obsolete since 24.4.  */
819
	  {
820
	    Lisp_Object handlers = POP, body = POP;
821
	    TOP = internal_lisp_condition_case (TOP, body, handlers);
Tom Tromey's avatar
Tom Tromey committed
822
	    NEXT;
823
	  }
Jim Blandy's avatar
Jim Blandy committed
824

Tom Tromey's avatar
Tom Tromey committed
825
	CASE (Btemp_output_buffer_setup): /* Obsolete since 24.1.  */
826
	  CHECK_STRING (TOP);
827
	  temp_output_buffer_setup (SSDATA (TOP));
Jim Blandy's avatar
Jim Blandy committed
828
	  TOP = Vstandard_output;
Tom Tromey's avatar
Tom Tromey committed
829
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
830

Tom Tromey's avatar
Tom Tromey committed
831
	CASE (Btemp_output_buffer_show): /* Obsolete since 24.1.  */
832
	  {
833
	    Lisp_Object v1 = POP;
834 835 836
	    temp_output_buffer_show (TOP);
	    TOP = v1;
	    /* pop binding of standard-output */
Juanma Barranquero's avatar
Juanma Barranquero committed
837
	    unbind_to (SPECPDL_INDEX () - 1, Qnil);
Tom Tromey's avatar
Tom Tromey committed
838
	    NEXT;
839
	  }
Jim Blandy's avatar
Jim Blandy committed
840

Tom Tromey's avatar
Tom Tromey committed
841
	CASE (Bnth):
842
	  {
843 844 845 846 847 848 849 850
	    Lisp_Object v2 = POP, v1 = TOP;
	    CHECK_NUMBER (v1);
	    EMACS_INT n = XINT (v1);
	    immediate_quit = true;
	    while (--n >= 0 && CONSP (v2))
	      v2 = XCDR (v2);
	    immediate_quit = false;
	    TOP = CAR (v2);
Tom Tromey's avatar
Tom Tromey committed
851
	    NEXT;
852
	  }
Jim Blandy's avatar
Jim Blandy committed
853

Tom Tromey's avatar
Tom Tromey committed
854
	CASE (Bsymbolp):
855
	  TOP = SYMBOLP (TOP) ? Qt : Qnil;
Tom Tromey's avatar
Tom Tromey committed
856
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
857

Tom Tromey's avatar
Tom Tromey committed
858
	CASE (Bconsp):
Jim Blandy's avatar
Jim Blandy committed
859
	  TOP = CONSP (TOP) ? Qt : Qnil;
Tom Tromey's avatar
Tom Tromey committed
860
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
861

Tom Tromey's avatar
Tom Tromey committed
862
	CASE (Bstringp):
863
	  TOP = STRINGP (TOP) ? Qt : Qnil;
Tom Tromey's avatar
Tom Tromey committed
864
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
865

Tom Tromey's avatar
Tom Tromey committed
866
	CASE (Blistp):
Joseph Arceneaux's avatar
Joseph Arceneaux committed
867
	  TOP = CONSP (TOP) || NILP (TOP) ? Qt : Qnil;
Tom Tromey's avatar
Tom Tromey committed
868
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
869

Tom Tromey's avatar
Tom Tromey committed
870
	CASE (Bnot):
Joseph Arceneaux's avatar
Joseph Arceneaux committed
871
	  TOP = NILP (TOP) ? Qt : Qnil;
Tom Tromey's avatar
Tom Tromey committed
872
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
873

Tom Tromey's avatar
Tom Tromey committed
874
	CASE (Bcons):
875
	  {
876
	    Lisp_Object v1 = POP;
877
	    TOP = Fcons (TOP, v1);
Tom Tromey's avatar
Tom Tromey committed
878
	    NEXT;
879
	  }
Jim Blandy's avatar
Jim Blandy committed
880

Tom Tromey's avatar
Tom Tromey committed
881
	CASE (Blist1):
882
	  TOP = list1 (TOP);
Tom Tromey's avatar
Tom Tromey committed
883
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
884

Tom Tromey's avatar
Tom Tromey committed
885
	CASE (Blist2):
886
	  {
887
	    Lisp_Object v1 = POP;
888
	    TOP = list2 (TOP, v1);
Tom Tromey's avatar
Tom Tromey committed
889
	    NEXT;
890
	  }
Jim Blandy's avatar
Jim Blandy committed
891

Tom Tromey's avatar
Tom Tromey committed
892
	CASE (Blist3):
893
	  DISCARD (2);
Jim Blandy's avatar
Jim Blandy committed
894
	  TOP = Flist (3, &TOP);
Tom Tromey's avatar
Tom Tromey committed
895
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
896

Tom Tromey's avatar
Tom Tromey committed
897
	CASE (Blist4):
898
	  DISCARD (3);
Jim Blandy's avatar
Jim Blandy committed
899
	  TOP = Flist (4, &TOP);
Tom Tromey's avatar
Tom Tromey committed
900
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
901

Tom Tromey's avatar
Tom Tromey committed
902
	CASE (BlistN):
903 904 905
	  op = FETCH;
	  DISCARD (op - 1);
	  TOP = Flist (op, &TOP);
Tom Tromey's avatar
Tom Tromey committed
906
	  NEXT;
907

Tom Tromey's avatar
Tom Tromey committed
908
	CASE (Blength):
Jim Blandy's avatar
Jim Blandy committed
909
	  TOP = Flength (TOP);
Tom Tromey's avatar
Tom Tromey committed
910
	  NEXT;
Jim Blandy's avatar
Jim Blandy committed
911

Tom Tromey's avatar
Tom Tromey committed
912
	CASE (Baref):
913
	  {
914
	    Lisp_Object v1 = POP;
915
	    TOP = Faref (TOP, v1);
Tom Tromey's avatar
Tom Tromey committed
916
	    NEXT;
917
	  }
Jim Blandy's avatar
Jim Blandy committed
918

Tom Tromey's avatar
Tom Tromey committed
919
	CASE (Baset):
920
	  {
921
	    Lisp_Object v2 = POP, v1 = POP;
922
	    TOP = Faset (TOP, v1, v2);