aboutsummaryrefslogtreecommitdiffstats
path: root/src/bytecode.c
diff options
context:
space:
mode:
authorNickolas Lloyd2016-12-22 19:06:36 -0500
committerNickolas Lloyd2016-12-22 19:06:36 -0500
commit61af5914d930787252685655b4d4d08a547ae833 (patch)
tree79b77574bab59a581e2355eaf5c12a9b1a2947ee /src/bytecode.c
parentee8bf252a020c02dcd025e41d258d178c788f3c8 (diff)
parentcf6ce9a1fe320ebe5b238af5f7af9416ac954855 (diff)
downloademacs-61af5914d930787252685655b4d4d08a547ae833.tar.gz
emacs-61af5914d930787252685655b4d4d08a547ae833.zip
; Merge branch 'master' into nick.lloyd-bytecode-jit
Diffstat (limited to 'src/bytecode.c')
-rw-r--r--src/bytecode.c824
1 files changed, 205 insertions, 619 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index b6b7484440f..c88ca509119 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -17,22 +17,6 @@ GNU General Public License for more details.
17You should have received a copy of the GNU General Public License 17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ 18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19 19
20/*
21hacked on by jwz@lucid.com 17-jun-91
22 o added a compile-time switch to turn on simple sanity checking;
23 o put back the obsolete byte-codes for error-detection;
24 o added a new instruction, unbind_all, which I will use for
25 tail-recursion elimination;
26 o made temp_output_buffer_show be called with the right number
27 of args;
28 o made the new bytecodes be called with args in the right order;
29 o added metering support.
30
31by Hallvard:
32 o added relative jump instructions;
33 o all conditionals now only do QUIT if they jump.
34 */
35
36#include <config.h> 20#include <config.h>
37 21
38#include "bytecode.h" 22#include "bytecode.h"
@@ -44,15 +28,16 @@ by Hallvard:
44#include "syntax.h" 28#include "syntax.h"
45#include "window.h" 29#include "window.h"
46 30
47#ifdef CHECK_FRAME_FONT 31/* Work around GCC bug 54561. */
48#include "frame.h" 32#if GNUC_PREREQ (4, 3, 0)
49#include "xterm.h" 33# pragma GCC diagnostic ignored "-Wclobbered"
50#endif 34#endif
51 35
52 36
53#ifdef BYTE_CODE_METER 37#ifdef BYTE_CODE_METER
54 38
55#define METER_2(code1, code2) AREF (AREF (Vbyte_code_meter, code1), code2) 39#define METER_2(code1, code2) \
40 (*aref_addr (AREF (Vbyte_code_meter, code1), code2))
56#define METER_1(code) METER_2 (0, code) 41#define METER_1(code) METER_2 (0, code)
57 42
58#define METER_CODE(last_code, this_code) \ 43#define METER_CODE(last_code, this_code) \
@@ -72,19 +57,14 @@ by Hallvard:
72 57
73#endif /* BYTE_CODE_METER */ 58#endif /* BYTE_CODE_METER */
74 59
75/* Declared in bytecode.h */
76struct byte_stack *byte_stack_list;
77
78 60
79/* Relocate program counters in the stacks on byte_stack_list. Called 61/* Relocate program counters in the stacks on byte_stack_list. Called
80 when GC has completed. */ 62 when GC has completed. */
81 63
82void 64void
83relocate_byte_stack (void) 65relocate_byte_stack (struct byte_stack *stack)
84{ 66{
85 struct byte_stack *stack; 67 for (; stack; stack = stack->next)
86
87 for (stack = byte_stack_list; stack; stack = stack->next)
88 { 68 {
89 if (stack->byte_string_start != SDATA (stack->byte_string)) 69 if (stack->byte_string_start != SDATA (stack->byte_string))
90 { 70 {
@@ -97,7 +77,6 @@ relocate_byte_stack (void)
97 77
98 78
99/* Fetch the next byte from the bytecode stream. */ 79/* Fetch the next byte from the bytecode stream. */
100
101#ifdef BYTE_CODE_SAFE 80#ifdef BYTE_CODE_SAFE
102#define FETCH (eassert (stack.byte_string_start == SDATA (stack.byte_string)), *stack.pc++) 81#define FETCH (eassert (stack.byte_string_start == SDATA (stack.byte_string)), *stack.pc++)
103#else 82#else
@@ -109,12 +88,10 @@ relocate_byte_stack (void)
109 88
110#define FETCH2 (op = FETCH, op + (FETCH << 8)) 89#define FETCH2 (op = FETCH, op + (FETCH << 8))
111 90
112/* Push x onto the execution stack. This used to be #define PUSH(x) 91/* Push X onto the execution stack. The expression X should not
113 (*++stackp = (x)) This oddity is necessary because Alliant can't be 92 contain TOP, to avoid competing side effects. */
114 bothered to compile the preincrement operator properly, as of 4/91.
115 -JimB */
116 93
117#define PUSH(x) (top++, *top = (x)) 94#define PUSH(x) (*++top = (x))
118 95
119/* Pop a value off the execution stack. */ 96/* Pop a value off the execution stack. */
120 97
@@ -129,33 +106,23 @@ relocate_byte_stack (void)
129 106
130#define TOP (*top) 107#define TOP (*top)
131 108
132/* Check for jumping out of range. */ 109#define CHECK_RANGE(ARG) \
133 110 (BYTE_CODE_SAFE && bytestr_length <= (ARG) ? emacs_abort () : (void) 0)
134#ifdef BYTE_CODE_SAFE
135
136#define CHECK_RANGE(ARG) \
137 if (ARG >= bytestr_length) emacs_abort ()
138
139#else /* not BYTE_CODE_SAFE */
140
141#define CHECK_RANGE(ARG)
142
143#endif /* not BYTE_CODE_SAFE */
144 111
145/* A version of the QUIT macro which makes sure that the stack top is 112/* A version of the QUIT macro which makes sure that the stack top is
146 set before signaling `quit'. */ 113 set before signaling `quit'. */
147
148#define BYTE_CODE_QUIT \ 114#define BYTE_CODE_QUIT \
149 do { \ 115 do { \
116 if (quitcounter++) \
117 break; \
118 maybe_gc (); \
150 if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \ 119 if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \
151 { \ 120 { \
152 Lisp_Object flag = Vquit_flag; \ 121 Lisp_Object flag = Vquit_flag; \
153 Vquit_flag = Qnil; \ 122 Vquit_flag = Qnil; \
154 BEFORE_POTENTIAL_GC (); \
155 if (EQ (Vthrow_on_input, flag)) \ 123 if (EQ (Vthrow_on_input, flag)) \
156 Fthrow (Vthrow_on_input, Qt); \ 124 Fthrow (Vthrow_on_input, Qt); \
157 Fsignal (Qquit, Qnil); \ 125 quit (); \
158 AFTER_POTENTIAL_GC (); \
159 } \ 126 } \
160 else if (pending_signals) \ 127 else if (pending_signals) \
161 process_pending_signals (); \ 128 process_pending_signals (); \
@@ -191,41 +158,15 @@ Lisp_Object
191exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, 158exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
192 Lisp_Object args_template, ptrdiff_t nargs, Lisp_Object *args) 159 Lisp_Object args_template, ptrdiff_t nargs, Lisp_Object *args)
193{ 160{
194 ptrdiff_t count = SPECPDL_INDEX ();
195#ifdef BYTE_CODE_METER 161#ifdef BYTE_CODE_METER
196 int volatile this_op = 0; 162 int volatile this_op = 0;
197 int prev_op;
198#endif
199 int op;
200 /* Lisp_Object v1, v2; */
201 Lisp_Object *vectorp;
202#ifdef BYTE_CODE_SAFE
203 ptrdiff_t const_length;
204 Lisp_Object *stacke;
205 ptrdiff_t bytestr_length;
206#endif
207 struct byte_stack stack;
208 Lisp_Object *top;
209 Lisp_Object result;
210 enum handlertype type;
211
212#if 0 /* CHECK_FRAME_FONT */
213 {
214 struct frame *f = SELECTED_FRAME ();
215 if (FRAME_X_P (f)
216 && FRAME_FONT (f)->direction != 0
217 && FRAME_FONT (f)->direction != 1)
218 emacs_abort ();
219 }
220#endif 163#endif
221 164
222 CHECK_STRING (bytestr); 165 CHECK_STRING (bytestr);
223 CHECK_VECTOR (vector); 166 CHECK_VECTOR (vector);
224 CHECK_NATNUM (maxdepth); 167 CHECK_NATNUM (maxdepth);
225 168
226#ifdef BYTE_CODE_SAFE 169 ptrdiff_t const_length = ASIZE (vector);
227 const_length = ASIZE (vector);
228#endif
229 170
230 if (STRING_MULTIBYTE (bytestr)) 171 if (STRING_MULTIBYTE (bytestr))
231 /* BYTESTR must have been produced by Emacs 20.2 or the earlier 172 /* BYTESTR must have been produced by Emacs 20.2 or the earlier
@@ -235,90 +176,60 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
235 convert them back to the originally intended unibyte form. */ 176 convert them back to the originally intended unibyte form. */
236 bytestr = Fstring_as_unibyte (bytestr); 177 bytestr = Fstring_as_unibyte (bytestr);
237 178
238#ifdef BYTE_CODE_SAFE 179 ptrdiff_t bytestr_length = SBYTES (bytestr);
239 bytestr_length = SBYTES (bytestr); 180 Lisp_Object *vectorp = XVECTOR (vector)->contents;
240#endif 181 struct byte_stack stack;
241 vectorp = XVECTOR (vector)->contents;
242 182
243 stack.byte_string = bytestr; 183 stack.byte_string = bytestr;
244 stack.pc = stack.byte_string_start = SDATA (bytestr); 184 stack.pc = stack.byte_string_start = SDATA (bytestr);
245 if (MAX_ALLOCA / word_size <= XFASTINT (maxdepth)) 185 unsigned char quitcounter = 0;
246 memory_full (SIZE_MAX); 186 EMACS_INT stack_items = XFASTINT (maxdepth) + 1;
247 top = alloca ((XFASTINT (maxdepth) + 1) * sizeof *top); 187 USE_SAFE_ALLOCA;
248#if BYTE_MAINTAIN_TOP 188 Lisp_Object *stack_base;
249 stack.bottom = top + 1; 189 SAFE_ALLOCA_LISP (stack_base, stack_items);
250 stack.top = NULL; 190 Lisp_Object *stack_lim = stack_base + stack_items;
251#endif 191 Lisp_Object *top = stack_base;
252 stack.next = byte_stack_list; 192 stack.next = byte_stack_list;
253 byte_stack_list = &stack; 193 byte_stack_list = &stack;
194 ptrdiff_t count = SPECPDL_INDEX ();
254 195
255#ifdef BYTE_CODE_SAFE 196 if (!NILP (args_template))
256 stacke = stack.bottom - 1 + XFASTINT (maxdepth);
257#endif
258
259 if (INTEGERP (args_template))
260 { 197 {
198 eassert (INTEGERP (args_template));
261 ptrdiff_t at = XINT (args_template); 199 ptrdiff_t at = XINT (args_template);
262 bool rest = (at & 128) != 0; 200 bool rest = (at & 128) != 0;
263 int mandatory = at & 127; 201 int mandatory = at & 127;
264 ptrdiff_t nonrest = at >> 8; 202 ptrdiff_t nonrest = at >> 8;
265 eassert (mandatory <= nonrest); 203 ptrdiff_t maxargs = rest ? PTRDIFF_MAX : nonrest;
266 if (nargs <= nonrest) 204 if (! (mandatory <= nargs && nargs <= maxargs))
267 {
268 ptrdiff_t i;
269 for (i = 0 ; i < nargs; i++, args++)
270 PUSH (*args);
271 if (nargs < mandatory)
272 /* Too few arguments. */
273 Fsignal (Qwrong_number_of_arguments,
274 list2 (Fcons (make_number (mandatory),
275 rest ? Qand_rest : make_number (nonrest)),
276 make_number (nargs)));
277 else
278 {
279 for (; i < nonrest; i++)
280 PUSH (Qnil);
281 if (rest)
282 PUSH (Qnil);
283 }
284 }
285 else if (rest)
286 {
287 ptrdiff_t i;
288 for (i = 0 ; i < nonrest; i++, args++)
289 PUSH (*args);
290 PUSH (Flist (nargs - nonrest, args));
291 }
292 else
293 /* Too many arguments. */
294 Fsignal (Qwrong_number_of_arguments, 205 Fsignal (Qwrong_number_of_arguments,
295 list2 (Fcons (make_number (mandatory), make_number (nonrest)), 206 list2 (Fcons (make_number (mandatory), make_number (nonrest)),
296 make_number (nargs))); 207 make_number (nargs)));
297 } 208 ptrdiff_t pushedargs = min (nonrest, nargs);
298 else if (! NILP (args_template)) 209 for (ptrdiff_t i = 0; i < pushedargs; i++, args++)
299 /* We should push some arguments on the stack. */ 210 PUSH (*args);
300 { 211 if (nonrest < nargs)
301 error ("Unknown args template!"); 212 PUSH (Flist (nargs - nonrest, args));
213 else
214 for (ptrdiff_t i = nargs - rest; i < nonrest; i++)
215 PUSH (Qnil);
302 } 216 }
303 217
304 while (1) 218 while (true)
305 { 219 {
306#ifdef BYTE_CODE_SAFE 220 int op;
307 if (top > stacke) 221 enum handlertype type;
308 emacs_abort (); 222
309 else if (top < stack.bottom - 1) 223 if (BYTE_CODE_SAFE && ! (stack_base <= top && top < stack_lim))
310 emacs_abort (); 224 emacs_abort ();
311#endif
312 225
313#ifdef BYTE_CODE_METER 226#ifdef BYTE_CODE_METER
314 prev_op = this_op; 227 int prev_op = this_op;
315 this_op = op = FETCH; 228 this_op = op = FETCH;
316 METER_CODE (prev_op, op); 229 METER_CODE (prev_op, op);
317#else 230#elif !defined BYTE_CODE_THREADED
318#ifndef BYTE_CODE_THREADED
319 op = FETCH; 231 op = FETCH;
320#endif 232#endif
321#endif
322 233
323 /* The interpreter can be compiled one of two ways: as an 234 /* The interpreter can be compiled one of two ways: as an
324 ordinary switch-based interpreter, or as a threaded 235 ordinary switch-based interpreter, or as a threaded
@@ -361,7 +272,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
361 the table clearer. */ 272 the table clearer. */
362#define LABEL(OP) [OP] = &&insn_ ## OP 273#define LABEL(OP) [OP] = &&insn_ ## OP
363 274
364#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) 275#if GNUC_PREREQ (4, 6, 0)
365# pragma GCC diagnostic push 276# pragma GCC diagnostic push
366# pragma GCC diagnostic ignored "-Woverride-init" 277# pragma GCC diagnostic ignored "-Woverride-init"
367#elif defined __clang__ 278#elif defined __clang__
@@ -380,7 +291,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
380#undef DEFINE 291#undef DEFINE
381 }; 292 };
382 293
383#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) || defined __clang__ 294#if GNUC_PREREQ (4, 6, 0) || defined __clang__
384# pragma GCC diagnostic pop 295# pragma GCC diagnostic pop
385#endif 296#endif
386 297
@@ -399,7 +310,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
399 CASE (Bvarref3): 310 CASE (Bvarref3):
400 CASE (Bvarref4): 311 CASE (Bvarref4):
401 CASE (Bvarref5): 312 CASE (Bvarref5):
402 op = op - Bvarref; 313 op -= Bvarref;
403 goto varref; 314 goto varref;
404 315
405 /* This seems to be the most frequently executed byte-code 316 /* This seems to be the most frequently executed byte-code
@@ -408,26 +319,11 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
408 op = FETCH; 319 op = FETCH;
409 varref: 320 varref:
410 { 321 {
411 Lisp_Object v1, v2; 322 Lisp_Object v1 = vectorp[op], v2;
412 323 if (!SYMBOLP (v1)
413 v1 = vectorp[op]; 324 || XSYMBOL (v1)->redirect != SYMBOL_PLAINVAL
414 if (SYMBOLP (v1)) 325 || (v2 = SYMBOL_VAL (XSYMBOL (v1)), EQ (v2, Qunbound)))
415 { 326 v2 = Fsymbol_value (v1);
416 if (XSYMBOL (v1)->redirect != SYMBOL_PLAINVAL
417 || (v2 = SYMBOL_VAL (XSYMBOL (v1)),
418 EQ (v2, Qunbound)))
419 {
420 BEFORE_POTENTIAL_GC ();
421 v2 = Fsymbol_value (v1);
422 AFTER_POTENTIAL_GC ();
423 }
424 }
425 else
426 {
427 BEFORE_POTENTIAL_GC ();
428 v2 = Fsymbol_value (v1);
429 AFTER_POTENTIAL_GC ();
430 }
431 PUSH (v2); 327 PUSH (v2);
432 NEXT; 328 NEXT;
433 } 329 }
@@ -435,7 +331,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
435 CASE (Bgotoifnil): 331 CASE (Bgotoifnil):
436 { 332 {
437 Lisp_Object v1; 333 Lisp_Object v1;
438 MAYBE_GC ();
439 op = FETCH2; 334 op = FETCH2;
440 v1 = POP; 335 v1 = POP;
441 if (NILP (v1)) 336 if (NILP (v1))
@@ -448,52 +343,32 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
448 } 343 }
449 344
450 CASE (Bcar): 345 CASE (Bcar):
451 { 346 if (CONSP (TOP))
452 Lisp_Object v1; 347 TOP = XCAR (TOP);
453 v1 = TOP; 348 else if (!NILP (TOP))
454 if (CONSP (v1)) 349 wrong_type_argument (Qlistp, TOP);
455 TOP = XCAR (v1); 350 NEXT;
456 else if (NILP (v1))
457 TOP = Qnil;
458 else
459 {
460 BEFORE_POTENTIAL_GC ();
461 wrong_type_argument (Qlistp, v1);
462 }
463 NEXT;
464 }
465 351
466 CASE (Beq): 352 CASE (Beq):
467 { 353 {
468 Lisp_Object v1; 354 Lisp_Object v1 = POP;
469 v1 = POP;
470 TOP = EQ (v1, TOP) ? Qt : Qnil; 355 TOP = EQ (v1, TOP) ? Qt : Qnil;
471 NEXT; 356 NEXT;
472 } 357 }
473 358
474 CASE (Bmemq): 359 CASE (Bmemq):
475 { 360 {
476 Lisp_Object v1; 361 Lisp_Object v1 = POP;
477 BEFORE_POTENTIAL_GC ();
478 v1 = POP;
479 TOP = Fmemq (TOP, v1); 362 TOP = Fmemq (TOP, v1);
480 AFTER_POTENTIAL_GC ();
481 NEXT; 363 NEXT;
482 } 364 }
483 365
484 CASE (Bcdr): 366 CASE (Bcdr):
485 { 367 {
486 Lisp_Object v1; 368 if (CONSP (TOP))
487 v1 = TOP; 369 TOP = XCDR (TOP);
488 if (CONSP (v1)) 370 else if (!NILP (TOP))
489 TOP = XCDR (v1); 371 wrong_type_argument (Qlistp, TOP);
490 else if (NILP (v1))
491 TOP = Qnil;
492 else
493 {
494 BEFORE_POTENTIAL_GC ();
495 wrong_type_argument (Qlistp, v1);
496 }
497 NEXT; 372 NEXT;
498 } 373 }
499 374
@@ -514,31 +389,23 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
514 op = FETCH; 389 op = FETCH;
515 varset: 390 varset:
516 { 391 {
517 Lisp_Object sym, val; 392 Lisp_Object sym = vectorp[op];
518 393 Lisp_Object val = POP;
519 sym = vectorp[op];
520 val = TOP;
521 394
522 /* Inline the most common case. */ 395 /* Inline the most common case. */
523 if (SYMBOLP (sym) 396 if (SYMBOLP (sym)
524 && !EQ (val, Qunbound) 397 && !EQ (val, Qunbound)
525 && !XSYMBOL (sym)->redirect 398 && !XSYMBOL (sym)->redirect
526 && !SYMBOL_CONSTANT_P (sym)) 399 && !SYMBOL_TRAPPED_WRITE_P (sym))
527 SET_SYMBOL_VAL (XSYMBOL (sym), val); 400 SET_SYMBOL_VAL (XSYMBOL (sym), val);
528 else 401 else
529 { 402 set_internal (sym, val, Qnil, SET_INTERNAL_SET);
530 BEFORE_POTENTIAL_GC ();
531 set_internal (sym, val, Qnil, 0);
532 AFTER_POTENTIAL_GC ();
533 }
534 } 403 }
535 (void) POP;
536 NEXT; 404 NEXT;
537 405
538 CASE (Bdup): 406 CASE (Bdup):
539 { 407 {
540 Lisp_Object v1; 408 Lisp_Object v1 = TOP;
541 v1 = TOP;
542 PUSH (v1); 409 PUSH (v1);
543 NEXT; 410 NEXT;
544 } 411 }
@@ -562,9 +429,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
562 op -= Bvarbind; 429 op -= Bvarbind;
563 varbind: 430 varbind:
564 /* Specbind can signal and thus GC. */ 431 /* Specbind can signal and thus GC. */
565 BEFORE_POTENTIAL_GC ();
566 specbind (vectorp[op], POP); 432 specbind (vectorp[op], POP);
567 AFTER_POTENTIAL_GC ();
568 NEXT; 433 NEXT;
569 434
570 CASE (Bcall6): 435 CASE (Bcall6):
@@ -584,15 +449,12 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
584 op -= Bcall; 449 op -= Bcall;
585 docall: 450 docall:
586 { 451 {
587 BEFORE_POTENTIAL_GC ();
588 DISCARD (op); 452 DISCARD (op);
589#ifdef BYTE_CODE_METER 453#ifdef BYTE_CODE_METER
590 if (byte_metering_on && SYMBOLP (TOP)) 454 if (byte_metering_on && SYMBOLP (TOP))
591 { 455 {
592 Lisp_Object v1, v2; 456 Lisp_Object v1 = TOP;
593 457 Lisp_Object v2 = Fget (v1, Qbyte_code_meter);
594 v1 = TOP;
595 v2 = Fget (v1, Qbyte_code_meter);
596 if (INTEGERP (v2) 458 if (INTEGERP (v2)
597 && XINT (v2) < MOST_POSITIVE_FIXNUM) 459 && XINT (v2) < MOST_POSITIVE_FIXNUM)
598 { 460 {
@@ -602,7 +464,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
602 } 464 }
603#endif 465#endif
604 TOP = Ffuncall (op + 1, &TOP); 466 TOP = Ffuncall (op + 1, &TOP);
605 AFTER_POTENTIAL_GC ();
606 NEXT; 467 NEXT;
607 } 468 }
608 469
@@ -622,21 +483,16 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
622 CASE (Bunbind5): 483 CASE (Bunbind5):
623 op -= Bunbind; 484 op -= Bunbind;
624 dounbind: 485 dounbind:
625 BEFORE_POTENTIAL_GC ();
626 unbind_to (SPECPDL_INDEX () - op, Qnil); 486 unbind_to (SPECPDL_INDEX () - op, Qnil);
627 AFTER_POTENTIAL_GC ();
628 NEXT; 487 NEXT;
629 488
630 CASE (Bunbind_all): /* Obsolete. Never used. */ 489 CASE (Bunbind_all): /* Obsolete. Never used. */
631 /* To unbind back to the beginning of this frame. Not used yet, 490 /* To unbind back to the beginning of this frame. Not used yet,
632 but will be needed for tail-recursion elimination. */ 491 but will be needed for tail-recursion elimination. */
633 BEFORE_POTENTIAL_GC ();
634 unbind_to (count, Qnil); 492 unbind_to (count, Qnil);
635 AFTER_POTENTIAL_GC ();
636 NEXT; 493 NEXT;
637 494
638 CASE (Bgoto): 495 CASE (Bgoto):
639 MAYBE_GC ();
640 BYTE_CODE_QUIT; 496 BYTE_CODE_QUIT;
641 op = FETCH2; /* pc = FETCH2 loses since FETCH2 contains pc++ */ 497 op = FETCH2; /* pc = FETCH2 loses since FETCH2 contains pc++ */
642 CHECK_RANGE (op); 498 CHECK_RANGE (op);
@@ -644,22 +500,17 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
644 NEXT; 500 NEXT;
645 501
646 CASE (Bgotoifnonnil): 502 CASE (Bgotoifnonnil):
647 { 503 op = FETCH2;
648 Lisp_Object v1; 504 Lisp_Object v1 = POP;
649 MAYBE_GC (); 505 if (!NILP (v1))
650 op = FETCH2; 506 {
651 v1 = POP; 507 BYTE_CODE_QUIT;
652 if (!NILP (v1)) 508 CHECK_RANGE (op);
653 { 509 stack.pc = stack.byte_string_start + op;
654 BYTE_CODE_QUIT; 510 }
655 CHECK_RANGE (op); 511 NEXT;
656 stack.pc = stack.byte_string_start + op;
657 }
658 NEXT;
659 }
660 512
661 CASE (Bgotoifnilelsepop): 513 CASE (Bgotoifnilelsepop):
662 MAYBE_GC ();
663 op = FETCH2; 514 op = FETCH2;
664 if (NILP (TOP)) 515 if (NILP (TOP))
665 { 516 {
@@ -671,7 +522,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
671 NEXT; 522 NEXT;
672 523
673 CASE (Bgotoifnonnilelsepop): 524 CASE (Bgotoifnonnilelsepop):
674 MAYBE_GC ();
675 op = FETCH2; 525 op = FETCH2;
676 if (!NILP (TOP)) 526 if (!NILP (TOP))
677 { 527 {
@@ -683,41 +533,29 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
683 NEXT; 533 NEXT;
684 534
685 CASE (BRgoto): 535 CASE (BRgoto):
686 MAYBE_GC ();
687 BYTE_CODE_QUIT; 536 BYTE_CODE_QUIT;
688 stack.pc += (int) *stack.pc - 127; 537 stack.pc += (int) *stack.pc - 127;
689 NEXT; 538 NEXT;
690 539
691 CASE (BRgotoifnil): 540 CASE (BRgotoifnil):
692 { 541 if (NILP (POP))
693 Lisp_Object v1; 542 {
694 MAYBE_GC (); 543 BYTE_CODE_QUIT;
695 v1 = POP; 544 stack.pc += (int) *stack.pc - 128;
696 if (NILP (v1)) 545 }
697 { 546 stack.pc++;
698 BYTE_CODE_QUIT; 547 NEXT;
699 stack.pc += (int) *stack.pc - 128;
700 }
701 stack.pc++;
702 NEXT;
703 }
704 548
705 CASE (BRgotoifnonnil): 549 CASE (BRgotoifnonnil):
706 { 550 if (!NILP (POP))
707 Lisp_Object v1; 551 {
708 MAYBE_GC (); 552 BYTE_CODE_QUIT;
709 v1 = POP; 553 stack.pc += (int) *stack.pc - 128;
710 if (!NILP (v1)) 554 }
711 { 555 stack.pc++;
712 BYTE_CODE_QUIT; 556 NEXT;
713 stack.pc += (int) *stack.pc - 128;
714 }
715 stack.pc++;
716 NEXT;
717 }
718 557
719 CASE (BRgotoifnilelsepop): 558 CASE (BRgotoifnilelsepop):
720 MAYBE_GC ();
721 op = *stack.pc++; 559 op = *stack.pc++;
722 if (NILP (TOP)) 560 if (NILP (TOP))
723 { 561 {
@@ -728,7 +566,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
728 NEXT; 566 NEXT;
729 567
730 CASE (BRgotoifnonnilelsepop): 568 CASE (BRgotoifnonnilelsepop):
731 MAYBE_GC ();
732 op = *stack.pc++; 569 op = *stack.pc++;
733 if (!NILP (TOP)) 570 if (!NILP (TOP))
734 { 571 {
@@ -739,7 +576,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
739 NEXT; 576 NEXT;
740 577
741 CASE (Breturn): 578 CASE (Breturn):
742 result = POP;
743 goto exit; 579 goto exit;
744 580
745 CASE (Bdiscard): 581 CASE (Bdiscard):
@@ -765,10 +601,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
765 ptrdiff_t count1 = SPECPDL_INDEX (); 601 ptrdiff_t count1 = SPECPDL_INDEX ();
766 record_unwind_protect (restore_window_configuration, 602 record_unwind_protect (restore_window_configuration,
767 Fcurrent_window_configuration (Qnil)); 603 Fcurrent_window_configuration (Qnil));
768 BEFORE_POTENTIAL_GC ();
769 TOP = Fprogn (TOP); 604 TOP = Fprogn (TOP);
770 unbind_to (count1, TOP); 605 unbind_to (count1, TOP);
771 AFTER_POTENTIAL_GC ();
772 NEXT; 606 NEXT;
773 } 607 }
774 608
@@ -779,11 +613,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
779 613
780 CASE (Bcatch): /* Obsolete since 24.4. */ 614 CASE (Bcatch): /* Obsolete since 24.4. */
781 { 615 {
782 Lisp_Object v1; 616 Lisp_Object v1 = POP;
783 BEFORE_POTENTIAL_GC ();
784 v1 = POP;
785 TOP = internal_catch (TOP, eval_sub, v1); 617 TOP = internal_catch (TOP, eval_sub, v1);
786 AFTER_POTENTIAL_GC ();
787 NEXT; 618 NEXT;
788 } 619 }
789 620
@@ -794,11 +625,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
794 type = CONDITION_CASE; 625 type = CONDITION_CASE;
795 pushhandler: 626 pushhandler:
796 { 627 {
797 Lisp_Object tag = POP; 628 struct handler *c = push_handler (POP, type);
798 int dest = FETCH2; 629 c->bytecode_dest = FETCH2;
799
800 struct handler *c = push_handler (tag, type);
801 c->bytecode_dest = dest;
802 c->bytecode_top = top; 630 c->bytecode_top = top;
803 631
804 if (sys_setjmp (c->jmp)) 632 if (sys_setjmp (c->jmp))
@@ -819,68 +647,51 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
819 } 647 }
820 648
821 CASE (Bpophandler): /* New in 24.4. */ 649 CASE (Bpophandler): /* New in 24.4. */
822 { 650 handlerlist = handlerlist->next;
823 handlerlist = handlerlist->next; 651 NEXT;
824 NEXT;
825 }
826 652
827 CASE (Bunwind_protect): /* FIXME: avoid closure for lexbind. */ 653 CASE (Bunwind_protect): /* FIXME: avoid closure for lexbind. */
828 { 654 {
829 Lisp_Object handler = POP; 655 Lisp_Object handler = POP;
830 /* Support for a function here is new in 24.4. */ 656 /* Support for a function here is new in 24.4. */
831 record_unwind_protect (NILP (Ffunctionp (handler)) 657 record_unwind_protect (FUNCTIONP (handler) ? bcall0 : unwind_body,
832 ? unwind_body : bcall0,
833 handler); 658 handler);
834 NEXT; 659 NEXT;
835 } 660 }
836 661
837 CASE (Bcondition_case): /* Obsolete since 24.4. */ 662 CASE (Bcondition_case): /* Obsolete since 24.4. */
838 { 663 {
839 Lisp_Object handlers, body; 664 Lisp_Object handlers = POP, body = POP;
840 handlers = POP;
841 body = POP;
842 BEFORE_POTENTIAL_GC ();
843 TOP = internal_lisp_condition_case (TOP, body, handlers); 665 TOP = internal_lisp_condition_case (TOP, body, handlers);
844 AFTER_POTENTIAL_GC ();
845 NEXT; 666 NEXT;
846 } 667 }
847 668
848 CASE (Btemp_output_buffer_setup): /* Obsolete since 24.1. */ 669 CASE (Btemp_output_buffer_setup): /* Obsolete since 24.1. */
849 BEFORE_POTENTIAL_GC ();
850 CHECK_STRING (TOP); 670 CHECK_STRING (TOP);
851 temp_output_buffer_setup (SSDATA (TOP)); 671 temp_output_buffer_setup (SSDATA (TOP));
852 AFTER_POTENTIAL_GC ();
853 TOP = Vstandard_output; 672 TOP = Vstandard_output;
854 NEXT; 673 NEXT;
855 674
856 CASE (Btemp_output_buffer_show): /* Obsolete since 24.1. */ 675 CASE (Btemp_output_buffer_show): /* Obsolete since 24.1. */
857 { 676 {
858 Lisp_Object v1; 677 Lisp_Object v1 = POP;
859 BEFORE_POTENTIAL_GC ();
860 v1 = POP;
861 temp_output_buffer_show (TOP); 678 temp_output_buffer_show (TOP);
862 TOP = v1; 679 TOP = v1;
863 /* pop binding of standard-output */ 680 /* pop binding of standard-output */
864 unbind_to (SPECPDL_INDEX () - 1, Qnil); 681 unbind_to (SPECPDL_INDEX () - 1, Qnil);
865 AFTER_POTENTIAL_GC ();
866 NEXT; 682 NEXT;
867 } 683 }
868 684
869 CASE (Bnth): 685 CASE (Bnth):
870 { 686 {
871 Lisp_Object v1, v2; 687 Lisp_Object v2 = POP, v1 = TOP;
872 EMACS_INT n; 688 CHECK_NUMBER (v1);
873 BEFORE_POTENTIAL_GC (); 689 EMACS_INT n = XINT (v1);
874 v1 = POP; 690 immediate_quit = true;
875 v2 = TOP; 691 while (--n >= 0 && CONSP (v2))
876 CHECK_NUMBER (v2); 692 v2 = XCDR (v2);
877 n = XINT (v2); 693 immediate_quit = false;
878 immediate_quit = 1; 694 TOP = CAR (v2);
879 while (--n >= 0 && CONSP (v1))
880 v1 = XCDR (v1);
881 immediate_quit = 0;
882 TOP = CAR (v1);
883 AFTER_POTENTIAL_GC ();
884 NEXT; 695 NEXT;
885 } 696 }
886 697
@@ -906,8 +717,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
906 717
907 CASE (Bcons): 718 CASE (Bcons):
908 { 719 {
909 Lisp_Object v1; 720 Lisp_Object v1 = POP;
910 v1 = POP;
911 TOP = Fcons (TOP, v1); 721 TOP = Fcons (TOP, v1);
912 NEXT; 722 NEXT;
913 } 723 }
@@ -918,8 +728,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
918 728
919 CASE (Blist2): 729 CASE (Blist2):
920 { 730 {
921 Lisp_Object v1; 731 Lisp_Object v1 = POP;
922 v1 = POP;
923 TOP = list2 (TOP, v1); 732 TOP = list2 (TOP, v1);
924 NEXT; 733 NEXT;
925 } 734 }
@@ -941,305 +750,191 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
941 NEXT; 750 NEXT;
942 751
943 CASE (Blength): 752 CASE (Blength):
944 BEFORE_POTENTIAL_GC ();
945 TOP = Flength (TOP); 753 TOP = Flength (TOP);
946 AFTER_POTENTIAL_GC ();
947 NEXT; 754 NEXT;
948 755
949 CASE (Baref): 756 CASE (Baref):
950 { 757 {
951 Lisp_Object v1; 758 Lisp_Object v1 = POP;
952 BEFORE_POTENTIAL_GC ();
953 v1 = POP;
954 TOP = Faref (TOP, v1); 759 TOP = Faref (TOP, v1);
955 AFTER_POTENTIAL_GC ();
956 NEXT; 760 NEXT;
957 } 761 }
958 762
959 CASE (Baset): 763 CASE (Baset):
960 { 764 {
961 Lisp_Object v1, v2; 765 Lisp_Object v2 = POP, v1 = POP;
962 BEFORE_POTENTIAL_GC ();
963 v2 = POP; v1 = POP;
964 TOP = Faset (TOP, v1, v2); 766 TOP = Faset (TOP, v1, v2);
965 AFTER_POTENTIAL_GC ();
966 NEXT; 767 NEXT;
967 } 768 }
968 769
969 CASE (Bsymbol_value): 770 CASE (Bsymbol_value):
970 BEFORE_POTENTIAL_GC ();
971 TOP = Fsymbol_value (TOP); 771 TOP = Fsymbol_value (TOP);
972 AFTER_POTENTIAL_GC ();
973 NEXT; 772 NEXT;
974 773
975 CASE (Bsymbol_function): 774 CASE (Bsymbol_function):
976 BEFORE_POTENTIAL_GC ();
977 TOP = Fsymbol_function (TOP); 775 TOP = Fsymbol_function (TOP);
978 AFTER_POTENTIAL_GC ();
979 NEXT; 776 NEXT;
980 777
981 CASE (Bset): 778 CASE (Bset):
982 { 779 {
983 Lisp_Object v1; 780 Lisp_Object v1 = POP;
984 BEFORE_POTENTIAL_GC ();
985 v1 = POP;
986 TOP = Fset (TOP, v1); 781 TOP = Fset (TOP, v1);
987 AFTER_POTENTIAL_GC ();
988 NEXT; 782 NEXT;
989 } 783 }
990 784
991 CASE (Bfset): 785 CASE (Bfset):
992 { 786 {
993 Lisp_Object v1; 787 Lisp_Object v1 = POP;
994 BEFORE_POTENTIAL_GC ();
995 v1 = POP;
996 TOP = Ffset (TOP, v1); 788 TOP = Ffset (TOP, v1);
997 AFTER_POTENTIAL_GC ();
998 NEXT; 789 NEXT;
999 } 790 }
1000 791
1001 CASE (Bget): 792 CASE (Bget):
1002 { 793 {
1003 Lisp_Object v1; 794 Lisp_Object v1 = POP;
1004 BEFORE_POTENTIAL_GC ();
1005 v1 = POP;
1006 TOP = Fget (TOP, v1); 795 TOP = Fget (TOP, v1);
1007 AFTER_POTENTIAL_GC ();
1008 NEXT; 796 NEXT;
1009 } 797 }
1010 798
1011 CASE (Bsubstring): 799 CASE (Bsubstring):
1012 { 800 {
1013 Lisp_Object v1, v2; 801 Lisp_Object v2 = POP, v1 = POP;
1014 BEFORE_POTENTIAL_GC ();
1015 v2 = POP; v1 = POP;
1016 TOP = Fsubstring (TOP, v1, v2); 802 TOP = Fsubstring (TOP, v1, v2);
1017 AFTER_POTENTIAL_GC ();
1018 NEXT; 803 NEXT;
1019 } 804 }
1020 805
1021 CASE (Bconcat2): 806 CASE (Bconcat2):
1022 BEFORE_POTENTIAL_GC ();
1023 DISCARD (1); 807 DISCARD (1);
1024 TOP = Fconcat (2, &TOP); 808 TOP = Fconcat (2, &TOP);
1025 AFTER_POTENTIAL_GC ();
1026 NEXT; 809 NEXT;
1027 810
1028 CASE (Bconcat3): 811 CASE (Bconcat3):
1029 BEFORE_POTENTIAL_GC ();
1030 DISCARD (2); 812 DISCARD (2);
1031 TOP = Fconcat (3, &TOP); 813 TOP = Fconcat (3, &TOP);
1032 AFTER_POTENTIAL_GC ();
1033 NEXT; 814 NEXT;
1034 815
1035 CASE (Bconcat4): 816 CASE (Bconcat4):
1036 BEFORE_POTENTIAL_GC ();
1037 DISCARD (3); 817 DISCARD (3);
1038 TOP = Fconcat (4, &TOP); 818 TOP = Fconcat (4, &TOP);
1039 AFTER_POTENTIAL_GC ();
1040 NEXT; 819 NEXT;
1041 820
1042 CASE (BconcatN): 821 CASE (BconcatN):
1043 op = FETCH; 822 op = FETCH;
1044 BEFORE_POTENTIAL_GC ();
1045 DISCARD (op - 1); 823 DISCARD (op - 1);
1046 TOP = Fconcat (op, &TOP); 824 TOP = Fconcat (op, &TOP);
1047 AFTER_POTENTIAL_GC ();
1048 NEXT; 825 NEXT;
1049 826
1050 CASE (Bsub1): 827 CASE (Bsub1):
1051 { 828 TOP = INTEGERP (TOP) ? make_number (XINT (TOP) - 1) : Fsub1 (TOP);
1052 Lisp_Object v1; 829 NEXT;
1053 v1 = TOP;
1054 if (INTEGERP (v1))
1055 {
1056 XSETINT (v1, XINT (v1) - 1);
1057 TOP = v1;
1058 }
1059 else
1060 {
1061 BEFORE_POTENTIAL_GC ();
1062 TOP = Fsub1 (v1);
1063 AFTER_POTENTIAL_GC ();
1064 }
1065 NEXT;
1066 }
1067 830
1068 CASE (Badd1): 831 CASE (Badd1):
1069 { 832 TOP = INTEGERP (TOP) ? make_number (XINT (TOP) + 1) : Fadd1 (TOP);
1070 Lisp_Object v1; 833 NEXT;
1071 v1 = TOP;
1072 if (INTEGERP (v1))
1073 {
1074 XSETINT (v1, XINT (v1) + 1);
1075 TOP = v1;
1076 }
1077 else
1078 {
1079 BEFORE_POTENTIAL_GC ();
1080 TOP = Fadd1 (v1);
1081 AFTER_POTENTIAL_GC ();
1082 }
1083 NEXT;
1084 }
1085 834
1086 CASE (Beqlsign): 835 CASE (Beqlsign):
1087 { 836 {
1088 Lisp_Object v1, v2; 837 Lisp_Object v2 = POP, v1 = TOP;
1089 BEFORE_POTENTIAL_GC ();
1090 v2 = POP; v1 = TOP;
1091 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (v1); 838 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (v1);
1092 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (v2); 839 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (v2);
1093 AFTER_POTENTIAL_GC (); 840 bool equal;
1094 if (FLOATP (v1) || FLOATP (v2)) 841 if (FLOATP (v1) || FLOATP (v2))
1095 { 842 {
1096 double f1, f2; 843 double f1 = FLOATP (v1) ? XFLOAT_DATA (v1) : XINT (v1);
1097 844 double f2 = FLOATP (v2) ? XFLOAT_DATA (v2) : XINT (v2);
1098 f1 = (FLOATP (v1) ? XFLOAT_DATA (v1) : XINT (v1)); 845 equal = f1 == f2;
1099 f2 = (FLOATP (v2) ? XFLOAT_DATA (v2) : XINT (v2));
1100 TOP = (f1 == f2 ? Qt : Qnil);
1101 } 846 }
1102 else 847 else
1103 TOP = (XINT (v1) == XINT (v2) ? Qt : Qnil); 848 equal = XINT (v1) == XINT (v2);
849 TOP = equal ? Qt : Qnil;
1104 NEXT; 850 NEXT;
1105 } 851 }
1106 852
1107 CASE (Bgtr): 853 CASE (Bgtr):
1108 { 854 {
1109 Lisp_Object v1; 855 Lisp_Object v1 = POP;
1110 BEFORE_POTENTIAL_GC ();
1111 v1 = POP;
1112 TOP = arithcompare (TOP, v1, ARITH_GRTR); 856 TOP = arithcompare (TOP, v1, ARITH_GRTR);
1113 AFTER_POTENTIAL_GC ();
1114 NEXT; 857 NEXT;
1115 } 858 }
1116 859
1117 CASE (Blss): 860 CASE (Blss):
1118 { 861 {
1119 Lisp_Object v1; 862 Lisp_Object v1 = POP;
1120 BEFORE_POTENTIAL_GC ();
1121 v1 = POP;
1122 TOP = arithcompare (TOP, v1, ARITH_LESS); 863 TOP = arithcompare (TOP, v1, ARITH_LESS);
1123 AFTER_POTENTIAL_GC ();
1124 NEXT; 864 NEXT;
1125 } 865 }
1126 866
1127 CASE (Bleq): 867 CASE (Bleq):
1128 { 868 {
1129 Lisp_Object v1; 869 Lisp_Object v1 = POP;
1130 BEFORE_POTENTIAL_GC ();
1131 v1 = POP;
1132 TOP = arithcompare (TOP, v1, ARITH_LESS_OR_EQUAL); 870 TOP = arithcompare (TOP, v1, ARITH_LESS_OR_EQUAL);
1133 AFTER_POTENTIAL_GC ();
1134 NEXT; 871 NEXT;
1135 } 872 }
1136 873
1137 CASE (Bgeq): 874 CASE (Bgeq):
1138 { 875 {
1139 Lisp_Object v1; 876 Lisp_Object v1 = POP;
1140 BEFORE_POTENTIAL_GC ();
1141 v1 = POP;
1142 TOP = arithcompare (TOP, v1, ARITH_GRTR_OR_EQUAL); 877 TOP = arithcompare (TOP, v1, ARITH_GRTR_OR_EQUAL);
1143 AFTER_POTENTIAL_GC ();
1144 NEXT; 878 NEXT;
1145 } 879 }
1146 880
1147 CASE (Bdiff): 881 CASE (Bdiff):
1148 BEFORE_POTENTIAL_GC ();
1149 DISCARD (1); 882 DISCARD (1);
1150 TOP = Fminus (2, &TOP); 883 TOP = Fminus (2, &TOP);
1151 AFTER_POTENTIAL_GC ();
1152 NEXT; 884 NEXT;
1153 885
1154 CASE (Bnegate): 886 CASE (Bnegate):
1155 { 887 TOP = INTEGERP (TOP) ? make_number (- XINT (TOP)) : Fminus (1, &TOP);
1156 Lisp_Object v1; 888 NEXT;
1157 v1 = TOP;
1158 if (INTEGERP (v1))
1159 {
1160 XSETINT (v1, - XINT (v1));
1161 TOP = v1;
1162 }
1163 else
1164 {
1165 BEFORE_POTENTIAL_GC ();
1166 TOP = Fminus (1, &TOP);
1167 AFTER_POTENTIAL_GC ();
1168 }
1169 NEXT;
1170 }
1171 889
1172 CASE (Bplus): 890 CASE (Bplus):
1173 BEFORE_POTENTIAL_GC ();
1174 DISCARD (1); 891 DISCARD (1);
1175 TOP = Fplus (2, &TOP); 892 TOP = Fplus (2, &TOP);
1176 AFTER_POTENTIAL_GC ();
1177 NEXT; 893 NEXT;
1178 894
1179 CASE (Bmax): 895 CASE (Bmax):
1180 BEFORE_POTENTIAL_GC ();
1181 DISCARD (1); 896 DISCARD (1);
1182 TOP = Fmax (2, &TOP); 897 TOP = Fmax (2, &TOP);
1183 AFTER_POTENTIAL_GC ();
1184 NEXT; 898 NEXT;
1185 899
1186 CASE (Bmin): 900 CASE (Bmin):
1187 BEFORE_POTENTIAL_GC ();
1188 DISCARD (1); 901 DISCARD (1);
1189 TOP = Fmin (2, &TOP); 902 TOP = Fmin (2, &TOP);
1190 AFTER_POTENTIAL_GC ();
1191 NEXT; 903 NEXT;
1192 904
1193 CASE (Bmult): 905 CASE (Bmult):
1194 BEFORE_POTENTIAL_GC ();
1195 DISCARD (1); 906 DISCARD (1);
1196 TOP = Ftimes (2, &TOP); 907 TOP = Ftimes (2, &TOP);
1197 AFTER_POTENTIAL_GC ();
1198 NEXT; 908 NEXT;
1199 909
1200 CASE (Bquo): 910 CASE (Bquo):
1201 BEFORE_POTENTIAL_GC ();
1202 DISCARD (1); 911 DISCARD (1);
1203 TOP = Fquo (2, &TOP); 912 TOP = Fquo (2, &TOP);
1204 AFTER_POTENTIAL_GC ();
1205 NEXT; 913 NEXT;
1206 914
1207 CASE (Brem): 915 CASE (Brem):
1208 { 916 {
1209 Lisp_Object v1; 917 Lisp_Object v1 = POP;
1210 BEFORE_POTENTIAL_GC ();
1211 v1 = POP;
1212 TOP = Frem (TOP, v1); 918 TOP = Frem (TOP, v1);
1213 AFTER_POTENTIAL_GC ();
1214 NEXT; 919 NEXT;
1215 } 920 }
1216 921
1217 CASE (Bpoint): 922 CASE (Bpoint):
1218 { 923 PUSH (make_natnum (PT));
1219 Lisp_Object v1; 924 NEXT;
1220 XSETFASTINT (v1, PT);
1221 PUSH (v1);
1222 NEXT;
1223 }
1224 925
1225 CASE (Bgoto_char): 926 CASE (Bgoto_char):
1226 BEFORE_POTENTIAL_GC ();
1227 TOP = Fgoto_char (TOP); 927 TOP = Fgoto_char (TOP);
1228 AFTER_POTENTIAL_GC ();
1229 NEXT; 928 NEXT;
1230 929
1231 CASE (Binsert): 930 CASE (Binsert):
1232 BEFORE_POTENTIAL_GC ();
1233 TOP = Finsert (1, &TOP); 931 TOP = Finsert (1, &TOP);
1234 AFTER_POTENTIAL_GC ();
1235 NEXT; 932 NEXT;
1236 933
1237 CASE (BinsertN): 934 CASE (BinsertN):
1238 op = FETCH; 935 op = FETCH;
1239 BEFORE_POTENTIAL_GC ();
1240 DISCARD (op - 1); 936 DISCARD (op - 1);
1241 TOP = Finsert (op, &TOP); 937 TOP = Finsert (op, &TOP);
1242 AFTER_POTENTIAL_GC ();
1243 NEXT; 938 NEXT;
1244 939
1245 CASE (Bpoint_max): 940 CASE (Bpoint_max):
@@ -1251,53 +946,27 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1251 } 946 }
1252 947
1253 CASE (Bpoint_min): 948 CASE (Bpoint_min):
1254 { 949 PUSH (make_natnum (BEGV));
1255 Lisp_Object v1; 950 NEXT;
1256 XSETFASTINT (v1, BEGV);
1257 PUSH (v1);
1258 NEXT;
1259 }
1260 951
1261 CASE (Bchar_after): 952 CASE (Bchar_after):
1262 BEFORE_POTENTIAL_GC ();
1263 TOP = Fchar_after (TOP); 953 TOP = Fchar_after (TOP);
1264 AFTER_POTENTIAL_GC ();
1265 NEXT; 954 NEXT;
1266 955
1267 CASE (Bfollowing_char): 956 CASE (Bfollowing_char):
1268 { 957 PUSH (Ffollowing_char ());
1269 Lisp_Object v1; 958 NEXT;
1270 BEFORE_POTENTIAL_GC ();
1271 v1 = Ffollowing_char ();
1272 AFTER_POTENTIAL_GC ();
1273 PUSH (v1);
1274 NEXT;
1275 }
1276 959
1277 CASE (Bpreceding_char): 960 CASE (Bpreceding_char):
1278 { 961 PUSH (Fprevious_char ());
1279 Lisp_Object v1; 962 NEXT;
1280 BEFORE_POTENTIAL_GC ();
1281 v1 = Fprevious_char ();
1282 AFTER_POTENTIAL_GC ();
1283 PUSH (v1);
1284 NEXT;
1285 }
1286 963
1287 CASE (Bcurrent_column): 964 CASE (Bcurrent_column):
1288 { 965 PUSH (make_natnum (current_column ()));
1289 Lisp_Object v1; 966 NEXT;
1290 BEFORE_POTENTIAL_GC ();
1291 XSETFASTINT (v1, current_column ());
1292 AFTER_POTENTIAL_GC ();
1293 PUSH (v1);
1294 NEXT;
1295 }
1296 967
1297 CASE (Bindent_to): 968 CASE (Bindent_to):
1298 BEFORE_POTENTIAL_GC ();
1299 TOP = Findent_to (TOP, Qnil); 969 TOP = Findent_to (TOP, Qnil);
1300 AFTER_POTENTIAL_GC ();
1301 NEXT; 970 NEXT;
1302 971
1303 CASE (Beolp): 972 CASE (Beolp):
@@ -1321,63 +990,43 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1321 NEXT; 990 NEXT;
1322 991
1323 CASE (Bset_buffer): 992 CASE (Bset_buffer):
1324 BEFORE_POTENTIAL_GC ();
1325 TOP = Fset_buffer (TOP); 993 TOP = Fset_buffer (TOP);
1326 AFTER_POTENTIAL_GC ();
1327 NEXT; 994 NEXT;
1328 995
1329 CASE (Binteractive_p): /* Obsolete since 24.1. */ 996 CASE (Binteractive_p): /* Obsolete since 24.1. */
1330 BEFORE_POTENTIAL_GC ();
1331 PUSH (call0 (intern ("interactive-p"))); 997 PUSH (call0 (intern ("interactive-p")));
1332 AFTER_POTENTIAL_GC ();
1333 NEXT; 998 NEXT;
1334 999
1335 CASE (Bforward_char): 1000 CASE (Bforward_char):
1336 BEFORE_POTENTIAL_GC ();
1337 TOP = Fforward_char (TOP); 1001 TOP = Fforward_char (TOP);
1338 AFTER_POTENTIAL_GC ();
1339 NEXT; 1002 NEXT;
1340 1003
1341 CASE (Bforward_word): 1004 CASE (Bforward_word):
1342 BEFORE_POTENTIAL_GC ();
1343 TOP = Fforward_word (TOP); 1005 TOP = Fforward_word (TOP);
1344 AFTER_POTENTIAL_GC ();
1345 NEXT; 1006 NEXT;
1346 1007
1347 CASE (Bskip_chars_forward): 1008 CASE (Bskip_chars_forward):
1348 { 1009 {
1349 Lisp_Object v1; 1010 Lisp_Object v1 = POP;
1350 BEFORE_POTENTIAL_GC ();
1351 v1 = POP;
1352 TOP = Fskip_chars_forward (TOP, v1); 1011 TOP = Fskip_chars_forward (TOP, v1);
1353 AFTER_POTENTIAL_GC ();
1354 NEXT; 1012 NEXT;
1355 } 1013 }
1356 1014
1357 CASE (Bskip_chars_backward): 1015 CASE (Bskip_chars_backward):
1358 { 1016 {
1359 Lisp_Object v1; 1017 Lisp_Object v1 = POP;
1360 BEFORE_POTENTIAL_GC ();
1361 v1 = POP;
1362 TOP = Fskip_chars_backward (TOP, v1); 1018 TOP = Fskip_chars_backward (TOP, v1);
1363 AFTER_POTENTIAL_GC ();
1364 NEXT; 1019 NEXT;
1365 } 1020 }
1366 1021
1367 CASE (Bforward_line): 1022 CASE (Bforward_line):
1368 BEFORE_POTENTIAL_GC ();
1369 TOP = Fforward_line (TOP); 1023 TOP = Fforward_line (TOP);
1370 AFTER_POTENTIAL_GC ();
1371 NEXT; 1024 NEXT;
1372 1025
1373 CASE (Bchar_syntax): 1026 CASE (Bchar_syntax):
1374 { 1027 {
1375 int c;
1376
1377 BEFORE_POTENTIAL_GC ();
1378 CHECK_CHARACTER (TOP); 1028 CHECK_CHARACTER (TOP);
1379 AFTER_POTENTIAL_GC (); 1029 int c = XFASTINT (TOP);
1380 c = XFASTINT (TOP);
1381 if (NILP (BVAR (current_buffer, enable_multibyte_characters))) 1030 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
1382 MAKE_CHAR_MULTIBYTE (c); 1031 MAKE_CHAR_MULTIBYTE (c);
1383 XSETFASTINT (TOP, syntax_code_spec[SYNTAX (c)]); 1032 XSETFASTINT (TOP, syntax_code_spec[SYNTAX (c)]);
@@ -1386,239 +1035,169 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1386 1035
1387 CASE (Bbuffer_substring): 1036 CASE (Bbuffer_substring):
1388 { 1037 {
1389 Lisp_Object v1; 1038 Lisp_Object v1 = POP;
1390 BEFORE_POTENTIAL_GC ();
1391 v1 = POP;
1392 TOP = Fbuffer_substring (TOP, v1); 1039 TOP = Fbuffer_substring (TOP, v1);
1393 AFTER_POTENTIAL_GC ();
1394 NEXT; 1040 NEXT;
1395 } 1041 }
1396 1042
1397 CASE (Bdelete_region): 1043 CASE (Bdelete_region):
1398 { 1044 {
1399 Lisp_Object v1; 1045 Lisp_Object v1 = POP;
1400 BEFORE_POTENTIAL_GC ();
1401 v1 = POP;
1402 TOP = Fdelete_region (TOP, v1); 1046 TOP = Fdelete_region (TOP, v1);
1403 AFTER_POTENTIAL_GC ();
1404 NEXT; 1047 NEXT;
1405 } 1048 }
1406 1049
1407 CASE (Bnarrow_to_region): 1050 CASE (Bnarrow_to_region):
1408 { 1051 {
1409 Lisp_Object v1; 1052 Lisp_Object v1 = POP;
1410 BEFORE_POTENTIAL_GC ();
1411 v1 = POP;
1412 TOP = Fnarrow_to_region (TOP, v1); 1053 TOP = Fnarrow_to_region (TOP, v1);
1413 AFTER_POTENTIAL_GC ();
1414 NEXT; 1054 NEXT;
1415 } 1055 }
1416 1056
1417 CASE (Bwiden): 1057 CASE (Bwiden):
1418 BEFORE_POTENTIAL_GC ();
1419 PUSH (Fwiden ()); 1058 PUSH (Fwiden ());
1420 AFTER_POTENTIAL_GC ();
1421 NEXT; 1059 NEXT;
1422 1060
1423 CASE (Bend_of_line): 1061 CASE (Bend_of_line):
1424 BEFORE_POTENTIAL_GC ();
1425 TOP = Fend_of_line (TOP); 1062 TOP = Fend_of_line (TOP);
1426 AFTER_POTENTIAL_GC ();
1427 NEXT; 1063 NEXT;
1428 1064
1429 CASE (Bset_marker): 1065 CASE (Bset_marker):
1430 { 1066 {
1431 Lisp_Object v1, v2; 1067 Lisp_Object v2 = POP, v1 = POP;
1432 BEFORE_POTENTIAL_GC (); 1068 TOP = Fset_marker (TOP, v1, v2);
1433 v1 = POP;
1434 v2 = POP;
1435 TOP = Fset_marker (TOP, v2, v1);
1436 AFTER_POTENTIAL_GC ();
1437 NEXT; 1069 NEXT;
1438 } 1070 }
1439 1071
1440 CASE (Bmatch_beginning): 1072 CASE (Bmatch_beginning):
1441 BEFORE_POTENTIAL_GC ();
1442 TOP = Fmatch_beginning (TOP); 1073 TOP = Fmatch_beginning (TOP);
1443 AFTER_POTENTIAL_GC ();
1444 NEXT; 1074 NEXT;
1445 1075
1446 CASE (Bmatch_end): 1076 CASE (Bmatch_end):
1447 BEFORE_POTENTIAL_GC ();
1448 TOP = Fmatch_end (TOP); 1077 TOP = Fmatch_end (TOP);
1449 AFTER_POTENTIAL_GC ();
1450 NEXT; 1078 NEXT;
1451 1079
1452 CASE (Bupcase): 1080 CASE (Bupcase):
1453 BEFORE_POTENTIAL_GC ();
1454 TOP = Fupcase (TOP); 1081 TOP = Fupcase (TOP);
1455 AFTER_POTENTIAL_GC ();
1456 NEXT; 1082 NEXT;
1457 1083
1458 CASE (Bdowncase): 1084 CASE (Bdowncase):
1459 BEFORE_POTENTIAL_GC ();
1460 TOP = Fdowncase (TOP); 1085 TOP = Fdowncase (TOP);
1461 AFTER_POTENTIAL_GC ();
1462 NEXT; 1086 NEXT;
1463 1087
1464 CASE (Bstringeqlsign): 1088 CASE (Bstringeqlsign):
1465 { 1089 {
1466 Lisp_Object v1; 1090 Lisp_Object v1 = POP;
1467 BEFORE_POTENTIAL_GC ();
1468 v1 = POP;
1469 TOP = Fstring_equal (TOP, v1); 1091 TOP = Fstring_equal (TOP, v1);
1470 AFTER_POTENTIAL_GC ();
1471 NEXT; 1092 NEXT;
1472 } 1093 }
1473 1094
1474 CASE (Bstringlss): 1095 CASE (Bstringlss):
1475 { 1096 {
1476 Lisp_Object v1; 1097 Lisp_Object v1 = POP;
1477 BEFORE_POTENTIAL_GC ();
1478 v1 = POP;
1479 TOP = Fstring_lessp (TOP, v1); 1098 TOP = Fstring_lessp (TOP, v1);
1480 AFTER_POTENTIAL_GC ();
1481 NEXT; 1099 NEXT;
1482 } 1100 }
1483 1101
1484 CASE (Bequal): 1102 CASE (Bequal):
1485 { 1103 {
1486 Lisp_Object v1; 1104 Lisp_Object v1 = POP;
1487 v1 = POP;
1488 TOP = Fequal (TOP, v1); 1105 TOP = Fequal (TOP, v1);
1489 NEXT; 1106 NEXT;
1490 } 1107 }
1491 1108
1492 CASE (Bnthcdr): 1109 CASE (Bnthcdr):
1493 { 1110 {
1494 Lisp_Object v1; 1111 Lisp_Object v1 = POP;
1495 BEFORE_POTENTIAL_GC ();
1496 v1 = POP;
1497 TOP = Fnthcdr (TOP, v1); 1112 TOP = Fnthcdr (TOP, v1);
1498 AFTER_POTENTIAL_GC ();
1499 NEXT; 1113 NEXT;
1500 } 1114 }
1501 1115
1502 CASE (Belt): 1116 CASE (Belt):
1503 { 1117 {
1504 Lisp_Object v1, v2;
1505 if (CONSP (TOP)) 1118 if (CONSP (TOP))
1506 { 1119 {
1507 /* Exchange args and then do nth. */ 1120 /* Exchange args and then do nth. */
1508 EMACS_INT n; 1121 Lisp_Object v2 = POP, v1 = TOP;
1509 BEFORE_POTENTIAL_GC ();
1510 v2 = POP;
1511 v1 = TOP;
1512 CHECK_NUMBER (v2); 1122 CHECK_NUMBER (v2);
1513 AFTER_POTENTIAL_GC (); 1123 EMACS_INT n = XINT (v2);
1514 n = XINT (v2); 1124 immediate_quit = true;
1515 immediate_quit = 1;
1516 while (--n >= 0 && CONSP (v1)) 1125 while (--n >= 0 && CONSP (v1))
1517 v1 = XCDR (v1); 1126 v1 = XCDR (v1);
1518 immediate_quit = 0; 1127 immediate_quit = false;
1519 TOP = CAR (v1); 1128 TOP = CAR (v1);
1520 } 1129 }
1521 else 1130 else
1522 { 1131 {
1523 BEFORE_POTENTIAL_GC (); 1132 Lisp_Object v1 = POP;
1524 v1 = POP;
1525 TOP = Felt (TOP, v1); 1133 TOP = Felt (TOP, v1);
1526 AFTER_POTENTIAL_GC ();
1527 } 1134 }
1528 NEXT; 1135 NEXT;
1529 } 1136 }
1530 1137
1531 CASE (Bmember): 1138 CASE (Bmember):
1532 { 1139 {
1533 Lisp_Object v1; 1140 Lisp_Object v1 = POP;
1534 BEFORE_POTENTIAL_GC ();
1535 v1 = POP;
1536 TOP = Fmember (TOP, v1); 1141 TOP = Fmember (TOP, v1);
1537 AFTER_POTENTIAL_GC ();
1538 NEXT; 1142 NEXT;
1539 } 1143 }
1540 1144
1541 CASE (Bassq): 1145 CASE (Bassq):
1542 { 1146 {
1543 Lisp_Object v1; 1147 Lisp_Object v1 = POP;
1544 BEFORE_POTENTIAL_GC ();
1545 v1 = POP;
1546 TOP = Fassq (TOP, v1); 1148 TOP = Fassq (TOP, v1);
1547 AFTER_POTENTIAL_GC ();
1548 NEXT; 1149 NEXT;
1549 } 1150 }
1550 1151
1551 CASE (Bnreverse): 1152 CASE (Bnreverse):
1552 BEFORE_POTENTIAL_GC ();
1553 TOP = Fnreverse (TOP); 1153 TOP = Fnreverse (TOP);
1554 AFTER_POTENTIAL_GC ();
1555 NEXT; 1154 NEXT;
1556 1155
1557 CASE (Bsetcar): 1156 CASE (Bsetcar):
1558 { 1157 {
1559 Lisp_Object v1; 1158 Lisp_Object v1 = POP;
1560 BEFORE_POTENTIAL_GC ();
1561 v1 = POP;
1562 TOP = Fsetcar (TOP, v1); 1159 TOP = Fsetcar (TOP, v1);
1563 AFTER_POTENTIAL_GC ();
1564 NEXT; 1160 NEXT;
1565 } 1161 }
1566 1162
1567 CASE (Bsetcdr): 1163 CASE (Bsetcdr):
1568 { 1164 {
1569 Lisp_Object v1; 1165 Lisp_Object v1 = POP;
1570 BEFORE_POTENTIAL_GC ();
1571 v1 = POP;
1572 TOP = Fsetcdr (TOP, v1); 1166 TOP = Fsetcdr (TOP, v1);
1573 AFTER_POTENTIAL_GC ();
1574 NEXT; 1167 NEXT;
1575 } 1168 }
1576 1169
1577 CASE (Bcar_safe): 1170 CASE (Bcar_safe):
1578 { 1171 TOP = CAR_SAFE (TOP);
1579 Lisp_Object v1; 1172 NEXT;
1580 v1 = TOP;
1581 TOP = CAR_SAFE (v1);
1582 NEXT;
1583 }
1584 1173
1585 CASE (Bcdr_safe): 1174 CASE (Bcdr_safe):
1586 { 1175 TOP = CDR_SAFE (TOP);
1587 Lisp_Object v1; 1176 NEXT;
1588 v1 = TOP;
1589 TOP = CDR_SAFE (v1);
1590 NEXT;
1591 }
1592 1177
1593 CASE (Bnconc): 1178 CASE (Bnconc):
1594 BEFORE_POTENTIAL_GC ();
1595 DISCARD (1); 1179 DISCARD (1);
1596 TOP = Fnconc (2, &TOP); 1180 TOP = Fnconc (2, &TOP);
1597 AFTER_POTENTIAL_GC ();
1598 NEXT; 1181 NEXT;
1599 1182
1600 CASE (Bnumberp): 1183 CASE (Bnumberp):
1601 TOP = (NUMBERP (TOP) ? Qt : Qnil); 1184 TOP = NUMBERP (TOP) ? Qt : Qnil;
1602 NEXT; 1185 NEXT;
1603 1186
1604 CASE (Bintegerp): 1187 CASE (Bintegerp):
1605 TOP = INTEGERP (TOP) ? Qt : Qnil; 1188 TOP = INTEGERP (TOP) ? Qt : Qnil;
1606 NEXT; 1189 NEXT;
1607 1190
1608#ifdef BYTE_CODE_SAFE 1191#if BYTE_CODE_SAFE
1609 /* These are intentionally written using 'case' syntax, 1192 /* These are intentionally written using 'case' syntax,
1610 because they are incompatible with the threaded 1193 because they are incompatible with the threaded
1611 interpreter. */ 1194 interpreter. */
1612 1195
1613 case Bset_mark: 1196 case Bset_mark:
1614 BEFORE_POTENTIAL_GC ();
1615 error ("set-mark is an obsolete bytecode"); 1197 error ("set-mark is an obsolete bytecode");
1616 AFTER_POTENTIAL_GC ();
1617 break; 1198 break;
1618 case Bscan_buffer: 1199 case Bscan_buffer:
1619 BEFORE_POTENTIAL_GC ();
1620 error ("scan-buffer is an obsolete bytecode"); 1200 error ("scan-buffer is an obsolete bytecode");
1621 AFTER_POTENTIAL_GC ();
1622 break; 1201 break;
1623#endif 1202#endif
1624 1203
@@ -1629,7 +1208,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1629 call3 (Qerror, 1208 call3 (Qerror,
1630 build_string ("Invalid byte opcode: op=%s, ptr=%d"), 1209 build_string ("Invalid byte opcode: op=%s, ptr=%d"),
1631 make_number (op), 1210 make_number (op),
1632 make_number ((stack.pc - 1) - stack.byte_string_start)); 1211 make_number (stack.pc - 1 - stack.byte_string_start));
1633 1212
1634 /* Handy byte-codes for lexical binding. */ 1213 /* Handy byte-codes for lexical binding. */
1635 CASE (Bstack_ref1): 1214 CASE (Bstack_ref1):
@@ -1638,32 +1217,32 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1638 CASE (Bstack_ref4): 1217 CASE (Bstack_ref4):
1639 CASE (Bstack_ref5): 1218 CASE (Bstack_ref5):
1640 { 1219 {
1641 Lisp_Object *ptr = top - (op - Bstack_ref); 1220 Lisp_Object v1 = top[Bstack_ref - op];
1642 PUSH (*ptr); 1221 PUSH (v1);
1643 NEXT; 1222 NEXT;
1644 } 1223 }
1645 CASE (Bstack_ref6): 1224 CASE (Bstack_ref6):
1646 { 1225 {
1647 Lisp_Object *ptr = top - (FETCH); 1226 Lisp_Object v1 = top[- FETCH];
1648 PUSH (*ptr); 1227 PUSH (v1);
1649 NEXT; 1228 NEXT;
1650 } 1229 }
1651 CASE (Bstack_ref7): 1230 CASE (Bstack_ref7):
1652 { 1231 {
1653 Lisp_Object *ptr = top - (FETCH2); 1232 Lisp_Object v1 = top[- FETCH2];
1654 PUSH (*ptr); 1233 PUSH (v1);
1655 NEXT; 1234 NEXT;
1656 } 1235 }
1657 CASE (Bstack_set): 1236 CASE (Bstack_set):
1658 /* stack-set-0 = discard; stack-set-1 = discard-1-preserve-tos. */ 1237 /* stack-set-0 = discard; stack-set-1 = discard-1-preserve-tos. */
1659 { 1238 {
1660 Lisp_Object *ptr = top - (FETCH); 1239 Lisp_Object *ptr = top - FETCH;
1661 *ptr = POP; 1240 *ptr = POP;
1662 NEXT; 1241 NEXT;
1663 } 1242 }
1664 CASE (Bstack_set2): 1243 CASE (Bstack_set2):
1665 { 1244 {
1666 Lisp_Object *ptr = top - (FETCH2); 1245 Lisp_Object *ptr = top - FETCH2;
1667 *ptr = POP; 1246 *ptr = POP;
1668 NEXT; 1247 NEXT;
1669 } 1248 }
@@ -1679,19 +1258,10 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1679 1258
1680 CASE_DEFAULT 1259 CASE_DEFAULT
1681 CASE (Bconstant): 1260 CASE (Bconstant):
1682#ifdef BYTE_CODE_SAFE 1261 if (BYTE_CODE_SAFE
1683 if (op < Bconstant) 1262 && ! (Bconstant <= op && op < Bconstant + const_length))
1684 { 1263 emacs_abort ();
1685 emacs_abort ();
1686 }
1687 if ((op -= Bconstant) >= const_length)
1688 {
1689 emacs_abort ();
1690 }
1691 PUSH (vectorp[op]);
1692#else
1693 PUSH (vectorp[op - Bconstant]); 1264 PUSH (vectorp[op - Bconstant]);
1694#endif
1695 NEXT; 1265 NEXT;
1696 } 1266 }
1697 } 1267 }
@@ -1708,9 +1278,25 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1708 error ("binding stack not balanced (serious byte compiler bug)"); 1278 error ("binding stack not balanced (serious byte compiler bug)");
1709 } 1279 }
1710 1280
1281 Lisp_Object result = TOP;
1282 SAFE_FREE ();
1711 return result; 1283 return result;
1712} 1284}
1713 1285
1286/* `args_template' has the same meaning as in exec_byte_code() above. */
1287Lisp_Object
1288get_byte_code_arity (Lisp_Object args_template)
1289{
1290 eassert (NATNUMP (args_template));
1291 EMACS_INT at = XINT (args_template);
1292 bool rest = (at & 128) != 0;
1293 int mandatory = at & 127;
1294 EMACS_INT nonrest = at >> 8;
1295
1296 return Fcons (make_number (mandatory),
1297 rest ? Qmany : make_number (nonrest));
1298}
1299
1714void 1300void
1715syms_of_bytecode (void) 1301syms_of_bytecode (void)
1716{ 1302{
@@ -1732,7 +1318,7 @@ The variable byte-code-meter indicates how often each byte opcode is used.
1732If a symbol has a property named `byte-code-meter' whose value is an 1318If a symbol has a property named `byte-code-meter' whose value is an
1733integer, it is incremented each time that symbol's function is called. */); 1319integer, it is incremented each time that symbol's function is called. */);
1734 1320
1735 byte_metering_on = 0; 1321 byte_metering_on = false;
1736 Vbyte_code_meter = Fmake_vector (make_number (256), make_number (0)); 1322 Vbyte_code_meter = Fmake_vector (make_number (256), make_number (0));
1737 DEFSYM (Qbyte_code_meter, "byte-code-meter"); 1323 DEFSYM (Qbyte_code_meter, "byte-code-meter");
1738 { 1324 {