* bytecode.c (MAYBE_GC): Rewrite so as not to use empty "else".
[bpt/emacs.git] / src / bytecode.c
CommitLineData
36f7ba0a 1/* Execution of byte code produced by bytecomp.el.
73b0cd50 2 Copyright (C) 1985-1988, 1993, 2000-2011 Free Software Foundation, Inc.
36f7ba0a
JB
3
4This file is part of GNU Emacs.
5
9ec0b715 6GNU Emacs is free software: you can redistribute it and/or modify
36f7ba0a 7it under the terms of the GNU General Public License as published by
9ec0b715
GM
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
36f7ba0a
JB
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
9ec0b715 17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
36f7ba0a 18
9ec0b715 19/*
63639d44 20hacked on by jwz@lucid.com 17-jun-91
36f7ba0a
JB
21 o added a compile-time switch to turn on simple sanity checking;
22 o put back the obsolete byte-codes for error-detection;
8e11578b 23 o added a new instruction, unbind_all, which I will use for
36f7ba0a 24 tail-recursion elimination;
63639d44 25 o made temp_output_buffer_show be called with the right number
36f7ba0a
JB
26 of args;
27 o made the new bytecodes be called with args in the right order;
28 o added metering support.
29
30by Hallvard:
3ffbe76b 31 o added relative jump instructions;
36f7ba0a
JB
32 o all conditionals now only do QUIT if they jump.
33 */
34
18160b98 35#include <config.h>
d7306fe6 36#include <setjmp.h>
36f7ba0a
JB
37#include "lisp.h"
38#include "buffer.h"
83be827a 39#include "character.h"
36f7ba0a 40#include "syntax.h"
3f6abfd7 41#include "window.h"
36f7ba0a 42
ad7de7d7
GM
43#ifdef CHECK_FRAME_FONT
44#include "frame.h"
45#include "xterm.h"
46#endif
47
63639d44 48/*
8e11578b 49 * define BYTE_CODE_SAFE to enable some minor sanity checking (useful for
63639d44
JB
50 * debugging the byte compiler...)
51 *
8e11578b 52 * define BYTE_CODE_METER to enable generation of a byte-op usage histogram.
36f7ba0a 53 */
63639d44
JB
54/* #define BYTE_CODE_SAFE */
55/* #define BYTE_CODE_METER */
36f7ba0a
JB
56
57\f
58#ifdef BYTE_CODE_METER
59
29208e82 60Lisp_Object Qbyte_code_meter;
63639d44 61#define METER_2(code1, code2) \
36f7ba0a
JB
62 XFASTINT (XVECTOR (XVECTOR (Vbyte_code_meter)->contents[(code1)]) \
63 ->contents[(code2)])
64
63639d44
JB
65#define METER_1(code) METER_2 (0, (code))
66
2e3bf02a
GM
67#define METER_CODE(last_code, this_code) \
68{ \
69 if (byte_metering_on) \
70 { \
71 if (METER_1 (this_code) < MOST_POSITIVE_FIXNUM) \
72 METER_1 (this_code)++; \
73 if (last_code \
74 && METER_2 (last_code, this_code) < MOST_POSITIVE_FIXNUM) \
75 METER_2 (last_code, this_code)++; \
76 } \
63639d44 77}
36f7ba0a 78
63639d44 79#else /* no BYTE_CODE_METER */
36f7ba0a 80
63639d44 81#define METER_CODE(last_code, this_code)
044512ed 82
63639d44 83#endif /* no BYTE_CODE_METER */
36f7ba0a
JB
84\f
85
86Lisp_Object Qbytecode;
87
88/* Byte codes: */
89
90#define Bvarref 010
91#define Bvarset 020
92#define Bvarbind 030
93#define Bcall 040
94#define Bunbind 050
95
96#define Bnth 070
97#define Bsymbolp 071
98#define Bconsp 072
99#define Bstringp 073
100#define Blistp 074
101#define Beq 075
102#define Bmemq 076
103#define Bnot 077
104#define Bcar 0100
105#define Bcdr 0101
106#define Bcons 0102
107#define Blist1 0103
108#define Blist2 0104
109#define Blist3 0105
110#define Blist4 0106
111#define Blength 0107
112#define Baref 0110
113#define Baset 0111
114#define Bsymbol_value 0112
63639d44 115#define Bsymbol_function 0113
36f7ba0a 116#define Bset 0114
63639d44 117#define Bfset 0115
36f7ba0a
JB
118#define Bget 0116
119#define Bsubstring 0117
120#define Bconcat2 0120
121#define Bconcat3 0121
122#define Bconcat4 0122
123#define Bsub1 0123
124#define Badd1 0124
125#define Beqlsign 0125
126#define Bgtr 0126
127#define Blss 0127
128#define Bleq 0130
129#define Bgeq 0131
130#define Bdiff 0132
131#define Bnegate 0133
132#define Bplus 0134
133#define Bmax 0135
134#define Bmin 0136
135#define Bmult 0137
136
137#define Bpoint 0140
3b841abc
RS
138/* Was Bmark in v17. */
139#define Bsave_current_buffer 0141
36f7ba0a
JB
140#define Bgoto_char 0142
141#define Binsert 0143
142#define Bpoint_max 0144
143#define Bpoint_min 0145
144#define Bchar_after 0146
145#define Bfollowing_char 0147
146#define Bpreceding_char 0150
147#define Bcurrent_column 0151
148#define Bindent_to 0152
149#define Bscan_buffer 0153 /* No longer generated as of v18 */
150#define Beolp 0154
151#define Beobp 0155
152#define Bbolp 0156
153#define Bbobp 0157
154#define Bcurrent_buffer 0160
155#define Bset_buffer 0161
80402f25 156#define Bsave_current_buffer_1 0162 /* Replacing Bsave_current_buffer. */
63639d44 157#define Bread_char 0162 /* No longer generated as of v19 */
36f7ba0a
JB
158#define Bset_mark 0163 /* this loser is no longer generated as of v18 */
159#define Binteractive_p 0164 /* Needed since interactive-p takes unevalled args */
160
161#define Bforward_char 0165
162#define Bforward_word 0166
163#define Bskip_chars_forward 0167
164#define Bskip_chars_backward 0170
165#define Bforward_line 0171
166#define Bchar_syntax 0172
167#define Bbuffer_substring 0173
168#define Bdelete_region 0174
169#define Bnarrow_to_region 0175
170#define Bwiden 0176
63639d44 171#define Bend_of_line 0177
36f7ba0a
JB
172
173#define Bconstant2 0201
174#define Bgoto 0202
175#define Bgotoifnil 0203
176#define Bgotoifnonnil 0204
177#define Bgotoifnilelsepop 0205
178#define Bgotoifnonnilelsepop 0206
179#define Breturn 0207
180#define Bdiscard 0210
181#define Bdup 0211
182
183#define Bsave_excursion 0212
184#define Bsave_window_excursion 0213
185#define Bsave_restriction 0214
186#define Bcatch 0215
187
188#define Bunwind_protect 0216
189#define Bcondition_case 0217
190#define Btemp_output_buffer_setup 0220
191#define Btemp_output_buffer_show 0221
192
193#define Bunbind_all 0222
194
63639d44
JB
195#define Bset_marker 0223
196#define Bmatch_beginning 0224
197#define Bmatch_end 0225
198#define Bupcase 0226
199#define Bdowncase 0227
200
36f7ba0a
JB
201#define Bstringeqlsign 0230
202#define Bstringlss 0231
203#define Bequal 0232
204#define Bnthcdr 0233
205#define Belt 0234
206#define Bmember 0235
207#define Bassq 0236
208#define Bnreverse 0237
209#define Bsetcar 0240
210#define Bsetcdr 0241
211#define Bcar_safe 0242
212#define Bcdr_safe 0243
213#define Bnconc 0244
214#define Bquo 0245
215#define Brem 0246
216#define Bnumberp 0247
217#define Bintegerp 0250
218
63639d44
JB
219#define BRgoto 0252
220#define BRgotoifnil 0253
221#define BRgotoifnonnil 0254
222#define BRgotoifnilelsepop 0255
223#define BRgotoifnonnilelsepop 0256
224
225#define BlistN 0257
226#define BconcatN 0260
227#define BinsertN 0261
228
36f7ba0a
JB
229#define Bconstant 0300
230#define CONSTANTLIM 0100
7ca1e8b7 231
b286858c
SM
232/* Whether to maintain a `top' and `bottom' field in the stack frame. */
233#define BYTE_MAINTAIN_TOP (BYTE_CODE_SAFE || BYTE_MARK_STACK)
4015b3c0 234\f
7ca1e8b7
GM
235/* Structure describing a value stack used during byte-code execution
236 in Fbyte_code. */
237
238struct byte_stack
239{
240 /* Program counter. This points into the byte_string below
241 and is relocated when that string is relocated. */
33b6c007 242 const unsigned char *pc;
7ca1e8b7
GM
243
244 /* Top and bottom of stack. The bottom points to an area of memory
245 allocated with alloca in Fbyte_code. */
b286858c 246#if BYTE_MAINTAIN_TOP
7ca1e8b7 247 Lisp_Object *top, *bottom;
b286858c 248#endif
7ca1e8b7
GM
249
250 /* The string containing the byte-code, and its current address.
251 Storing this here protects it from GC because mark_byte_stack
252 marks it. */
253 Lisp_Object byte_string;
33b6c007 254 const unsigned char *byte_string_start;
7ca1e8b7
GM
255
256 /* The vector of constants used during byte-code execution. Storing
257 this here protects it from GC because mark_byte_stack marks it. */
258 Lisp_Object constants;
259
260 /* Next entry in byte_stack_list. */
261 struct byte_stack *next;
262};
263
264/* A list of currently active byte-code execution value stacks.
265 Fbyte_code adds an entry to the head of this list before it starts
266 processing byte-code, and it removed the entry again when it is
267 done. Signalling an error truncates the list analoguous to
268 gcprolist. */
269
270struct byte_stack *byte_stack_list;
271
4015b3c0 272\f
7ca1e8b7
GM
273/* Mark objects on byte_stack_list. Called during GC. */
274
b286858c 275#if BYTE_MARK_STACK
7ca1e8b7 276void
971de7fb 277mark_byte_stack (void)
7ca1e8b7
GM
278{
279 struct byte_stack *stack;
280 Lisp_Object *obj;
281
282 for (stack = byte_stack_list; stack; stack = stack->next)
283 {
dff13d03
GM
284 /* If STACK->top is null here, this means there's an opcode in
285 Fbyte_code that wasn't expected to GC, but did. To find out
286 which opcode this is, record the value of `stack', and walk
287 up the stack in a debugger, stopping in frames of Fbyte_code.
288 The culprit is found in the frame of Fbyte_code where the
289 address of its local variable `stack' is equal to the
290 recorded value of `stack' here. */
6b61353c 291 eassert (stack->top);
8e11578b 292
7ca1e8b7 293 for (obj = stack->bottom; obj <= stack->top; ++obj)
6b61353c 294 mark_object (*obj);
a719d13e 295
6b61353c
KH
296 mark_object (stack->byte_string);
297 mark_object (stack->constants);
7ca1e8b7
GM
298 }
299}
b286858c 300#endif
7ca1e8b7 301
a719d13e
GM
302/* Unmark objects in the stacks on byte_stack_list. Relocate program
303 counters. Called when GC has completed. */
7ca1e8b7 304
8e11578b 305void
971de7fb 306unmark_byte_stack (void)
7ca1e8b7
GM
307{
308 struct byte_stack *stack;
309
310 for (stack = byte_stack_list; stack; stack = stack->next)
a719d13e 311 {
d5db4077 312 if (stack->byte_string_start != SDATA (stack->byte_string))
a719d13e
GM
313 {
314 int offset = stack->pc - stack->byte_string_start;
d5db4077 315 stack->byte_string_start = SDATA (stack->byte_string);
a719d13e
GM
316 stack->pc = stack->byte_string_start + offset;
317 }
318 }
7ca1e8b7
GM
319}
320
36f7ba0a
JB
321\f
322/* Fetch the next byte from the bytecode stream */
323
7ca1e8b7 324#define FETCH *stack.pc++
36f7ba0a 325
4015b3c0
GM
326/* Fetch two bytes from the bytecode stream and make a 16-bit number
327 out of them */
36f7ba0a
JB
328
329#define FETCH2 (op = FETCH, op + (FETCH << 8))
330
4015b3c0
GM
331/* Push x onto the execution stack. This used to be #define PUSH(x)
332 (*++stackp = (x)) This oddity is necessary because Alliant can't be
333 bothered to compile the preincrement operator properly, as of 4/91.
334 -JimB */
7ca1e8b7
GM
335
336#define PUSH(x) (top++, *top = (x))
36f7ba0a
JB
337
338/* Pop a value off the execution stack. */
339
7ca1e8b7 340#define POP (*top--)
36f7ba0a
JB
341
342/* Discard n values from the execution stack. */
343
7ca1e8b7
GM
344#define DISCARD(n) (top -= (n))
345
346/* Get the value which is at the top of the execution stack, but don't
347 pop it. */
348
349#define TOP (*top)
36f7ba0a 350
4015b3c0 351/* Actions that must be performed before and after calling a function
7ca1e8b7 352 that might GC. */
36f7ba0a 353
b286858c
SM
354#if !BYTE_MAINTAIN_TOP
355#define BEFORE_POTENTIAL_GC() ((void)0)
356#define AFTER_POTENTIAL_GC() ((void)0)
357#else
7ca1e8b7
GM
358#define BEFORE_POTENTIAL_GC() stack.top = top
359#define AFTER_POTENTIAL_GC() stack.top = NULL
b286858c 360#endif
36f7ba0a 361
14726871
RS
362/* Garbage collect if we have consed enough since the last time.
363 We do this at every branch, to avoid loops that never GC. */
364
3414f2d8 365#define MAYBE_GC() \
7914961c 366 do { \
3414f2d8
RS
367 if (consing_since_gc > gc_cons_threshold \
368 && consing_since_gc > gc_relative_threshold) \
369 { \
370 BEFORE_POTENTIAL_GC (); \
371 Fgarbage_collect (); \
372 AFTER_POTENTIAL_GC (); \
373 } \
7914961c 374 } while (0)
5e7ed093 375
3d5fc37b 376/* Check for jumping out of range. */
7ca1e8b7
GM
377
378#ifdef BYTE_CODE_SAFE
379
4015b3c0 380#define CHECK_RANGE(ARG) \
3d5fc37b
RS
381 if (ARG >= bytestr_length) abort ()
382
4015b3c0 383#else /* not BYTE_CODE_SAFE */
7ca1e8b7
GM
384
385#define CHECK_RANGE(ARG)
386
4015b3c0 387#endif /* not BYTE_CODE_SAFE */
7ca1e8b7 388
e12ea64e
GM
389/* A version of the QUIT macro which makes sure that the stack top is
390 set before signaling `quit'. */
391
392#define BYTE_CODE_QUIT \
393 do { \
394 if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \
395 { \
731475e7 396 Lisp_Object flag = Vquit_flag; \
e12ea64e
GM
397 Vquit_flag = Qnil; \
398 BEFORE_POTENTIAL_GC (); \
731475e7 399 if (EQ (Vthrow_on_input, flag)) \
a8f0f551 400 Fthrow (Vthrow_on_input, Qt); \
e12ea64e 401 Fsignal (Qquit, Qnil); \
892a8eb5 402 AFTER_POTENTIAL_GC (); \
e12ea64e 403 } \
c0335e02 404 ELSE_PENDING_SIGNALS \
e12ea64e
GM
405 } while (0)
406
7ca1e8b7 407
36f7ba0a 408DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0,
39f624fa
PJ
409 doc: /* Function used internally in byte-compiled code.
410The first argument, BYTESTR, is a string of byte code;
411the second, VECTOR, a vector of constants;
412the third, MAXDEPTH, the maximum stack depth used in this function.
413If the third argument is incorrect, Emacs may crash. */)
5842a27b 414 (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth)
36f7ba0a 415{
aed13378 416 int count = SPECPDL_INDEX ();
36f7ba0a
JB
417#ifdef BYTE_CODE_METER
418 int this_op = 0;
419 int prev_op;
420#endif
7ca1e8b7 421 int op;
4015b3c0 422 /* Lisp_Object v1, v2; */
089b985f 423 Lisp_Object *vectorp;
36f7ba0a 424#ifdef BYTE_CODE_SAFE
7ca1e8b7
GM
425 int const_length = XVECTOR (vector)->size;
426 Lisp_Object *stacke;
36f7ba0a 427#endif
089b985f 428 int bytestr_length;
7ca1e8b7
GM
429 struct byte_stack stack;
430 Lisp_Object *top;
4015b3c0 431 Lisp_Object result;
36f7ba0a 432
603a0937 433#if 0 /* CHECK_FRAME_FONT */
ad7de7d7
GM
434 {
435 struct frame *f = SELECTED_FRAME ();
436 if (FRAME_X_P (f)
437 && FRAME_FONT (f)->direction != 0
438 && FRAME_FONT (f)->direction != 1)
439 abort ();
440 }
441#endif
442
b7826503 443 CHECK_STRING (bytestr);
c616acb8 444 CHECK_VECTOR (vector);
b7826503 445 CHECK_NUMBER (maxdepth);
36f7ba0a 446
089b985f
KH
447 if (STRING_MULTIBYTE (bytestr))
448 /* BYTESTR must have been produced by Emacs 20.2 or the earlier
449 because they produced a raw 8-bit string for byte-code and now
450 such a byte-code string is loaded as multibyte while raw 8-bit
451 characters converted to multibyte form. Thus, now we must
fbd98f82 452 convert them back to the originally intended unibyte form. */
5274126b 453 bytestr = Fstring_as_unibyte (bytestr);
089b985f 454
d5db4077 455 bytestr_length = SBYTES (bytestr);
089b985f
KH
456 vectorp = XVECTOR (vector)->contents;
457
7ca1e8b7 458 stack.byte_string = bytestr;
d5db4077 459 stack.pc = stack.byte_string_start = SDATA (bytestr);
7ca1e8b7 460 stack.constants = vector;
b286858c 461 top = (Lisp_Object *) alloca (XFASTINT (maxdepth)
7ca1e8b7 462 * sizeof (Lisp_Object));
b286858c
SM
463#if BYTE_MAINTAIN_TOP
464 stack.bottom = top;
7ca1e8b7 465 stack.top = NULL;
b286858c
SM
466#endif
467 top -= 1;
7ca1e8b7
GM
468 stack.next = byte_stack_list;
469 byte_stack_list = &stack;
36f7ba0a 470
7ca1e8b7
GM
471#ifdef BYTE_CODE_SAFE
472 stacke = stack.bottom - 1 + XFASTINT (maxdepth);
473#endif
8e11578b 474
36f7ba0a
JB
475 while (1)
476 {
477#ifdef BYTE_CODE_SAFE
9e49c990 478 if (top > stacke)
cc94f3b2 479 abort ();
7ca1e8b7 480 else if (top < stack.bottom - 1)
cc94f3b2 481 abort ();
36f7ba0a
JB
482#endif
483
36f7ba0a
JB
484#ifdef BYTE_CODE_METER
485 prev_op = this_op;
486 this_op = op = FETCH;
487 METER_CODE (prev_op, op);
36f7ba0a 488#else
4015b3c0 489 op = FETCH;
36f7ba0a 490#endif
36f7ba0a 491
4015b3c0
GM
492 switch (op)
493 {
494 case Bvarref + 7:
36f7ba0a
JB
495 op = FETCH2;
496 goto varref;
497
8e11578b
TTN
498 case Bvarref:
499 case Bvarref + 1:
500 case Bvarref + 2:
4015b3c0 501 case Bvarref + 3:
8e11578b 502 case Bvarref + 4:
4015b3c0 503 case Bvarref + 5:
36f7ba0a 504 op = op - Bvarref;
4015b3c0
GM
505 goto varref;
506
507 /* This seems to be the most frequently executed byte-code
508 among the Bvarref's, so avoid a goto here. */
509 case Bvarref+6:
510 op = FETCH;
36f7ba0a 511 varref:
4015b3c0
GM
512 {
513 Lisp_Object v1, v2;
514
515 v1 = vectorp[op];
516 if (SYMBOLP (v1))
517 {
ce5b453a
SM
518 if (XSYMBOL (v1)->redirect != SYMBOL_PLAINVAL
519 || (v2 = SYMBOL_VAL (XSYMBOL (v1)),
520 EQ (v2, Qunbound)))
bf1de43e
GM
521 {
522 BEFORE_POTENTIAL_GC ();
523 v2 = Fsymbol_value (v1);
524 AFTER_POTENTIAL_GC ();
525 }
4015b3c0
GM
526 }
527 else
bf1de43e
GM
528 {
529 BEFORE_POTENTIAL_GC ();
530 v2 = Fsymbol_value (v1);
531 AFTER_POTENTIAL_GC ();
532 }
4015b3c0
GM
533 PUSH (v2);
534 break;
535 }
536
537 case Bgotoifnil:
21ed6de3
KR
538 {
539 Lisp_Object v1;
540 MAYBE_GC ();
541 op = FETCH2;
542 v1 = POP;
543 if (NILP (v1))
544 {
545 BYTE_CODE_QUIT;
546 CHECK_RANGE (op);
547 stack.pc = stack.byte_string_start + op;
548 }
549 break;
550 }
36f7ba0a 551
4015b3c0
GM
552 case Bcar:
553 {
554 Lisp_Object v1;
555 v1 = TOP;
14c5155a 556 TOP = CAR (v1);
4015b3c0
GM
557 break;
558 }
559
560 case Beq:
561 {
562 Lisp_Object v1;
563 v1 = POP;
564 TOP = EQ (v1, TOP) ? Qt : Qnil;
565 break;
566 }
567
568 case Bmemq:
569 {
570 Lisp_Object v1;
bf1de43e 571 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
572 v1 = POP;
573 TOP = Fmemq (TOP, v1);
bf1de43e 574 AFTER_POTENTIAL_GC ();
4015b3c0
GM
575 break;
576 }
577
578 case Bcdr:
579 {
580 Lisp_Object v1;
581 v1 = TOP;
14c5155a 582 TOP = CDR (v1);
4015b3c0
GM
583 break;
584 }
36f7ba0a 585
620cc5fa
GM
586 case Bvarset:
587 case Bvarset+1:
588 case Bvarset+2:
589 case Bvarset+3:
590 case Bvarset+4:
591 case Bvarset+5:
592 op -= Bvarset;
36f7ba0a
JB
593 goto varset;
594
620cc5fa
GM
595 case Bvarset+7:
596 op = FETCH2;
4015b3c0
GM
597 goto varset;
598
599 case Bvarset+6:
600 op = FETCH;
36f7ba0a 601 varset:
620cc5fa
GM
602 {
603 Lisp_Object sym, val;
8e11578b 604
620cc5fa 605 sym = vectorp[op];
bf1de43e 606 val = TOP;
620cc5fa
GM
607
608 /* Inline the most common case. */
609 if (SYMBOLP (sym)
610 && !EQ (val, Qunbound)
ce5b453a
SM
611 && !XSYMBOL (sym)->redirect
612 && !SYMBOL_CONSTANT_P (sym))
613 XSYMBOL (sym)->val.value = val;
620cc5fa 614 else
bf1de43e
GM
615 {
616 BEFORE_POTENTIAL_GC ();
94b612ad 617 set_internal (sym, val, Qnil, 0);
bf1de43e
GM
618 AFTER_POTENTIAL_GC ();
619 }
620cc5fa 620 }
3789dcdf 621 (void) POP;
36f7ba0a
JB
622 break;
623
4015b3c0
GM
624 case Bdup:
625 {
626 Lisp_Object v1;
627 v1 = TOP;
628 PUSH (v1);
629 break;
630 }
631
632 /* ------------------ */
633
36f7ba0a
JB
634 case Bvarbind+6:
635 op = FETCH;
636 goto varbind;
637
638 case Bvarbind+7:
639 op = FETCH2;
640 goto varbind;
641
fa9aabf6
GM
642 case Bvarbind:
643 case Bvarbind+1:
644 case Bvarbind+2:
645 case Bvarbind+3:
646 case Bvarbind+4:
647 case Bvarbind+5:
36f7ba0a
JB
648 op -= Bvarbind;
649 varbind:
56b8eef5
GM
650 /* Specbind can signal and thus GC. */
651 BEFORE_POTENTIAL_GC ();
36f7ba0a 652 specbind (vectorp[op], POP);
56b8eef5 653 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
654 break;
655
656 case Bcall+6:
657 op = FETCH;
658 goto docall;
659
660 case Bcall+7:
661 op = FETCH2;
662 goto docall;
663
fa9aabf6
GM
664 case Bcall:
665 case Bcall+1:
666 case Bcall+2:
667 case Bcall+3:
668 case Bcall+4:
669 case Bcall+5:
36f7ba0a
JB
670 op -= Bcall;
671 docall:
4015b3c0 672 {
fa9aabf6 673 BEFORE_POTENTIAL_GC ();
4015b3c0 674 DISCARD (op);
63639d44 675#ifdef BYTE_CODE_METER
4015b3c0
GM
676 if (byte_metering_on && SYMBOLP (TOP))
677 {
678 Lisp_Object v1, v2;
679
680 v1 = TOP;
681 v2 = Fget (v1, Qbyte_code_meter);
682 if (INTEGERP (v2)
f28e6371 683 && XINT (v2) < MOST_POSITIVE_FIXNUM)
4015b3c0
GM
684 {
685 XSETINT (v2, XINT (v2) + 1);
686 Fput (v1, Qbyte_code_meter, v2);
687 }
688 }
63639d44 689#endif
4015b3c0
GM
690 TOP = Ffuncall (op + 1, &TOP);
691 AFTER_POTENTIAL_GC ();
692 break;
693 }
36f7ba0a
JB
694
695 case Bunbind+6:
696 op = FETCH;
697 goto dounbind;
698
699 case Bunbind+7:
700 op = FETCH2;
701 goto dounbind;
702
fa9aabf6
GM
703 case Bunbind:
704 case Bunbind+1:
705 case Bunbind+2:
706 case Bunbind+3:
707 case Bunbind+4:
708 case Bunbind+5:
36f7ba0a
JB
709 op -= Bunbind;
710 dounbind:
7ca1e8b7 711 BEFORE_POTENTIAL_GC ();
aed13378 712 unbind_to (SPECPDL_INDEX () - op, Qnil);
7ca1e8b7 713 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
714 break;
715
716 case Bunbind_all:
717 /* To unbind back to the beginning of this frame. Not used yet,
63639d44 718 but will be needed for tail-recursion elimination. */
7ca1e8b7 719 BEFORE_POTENTIAL_GC ();
36f7ba0a 720 unbind_to (count, Qnil);
7ca1e8b7 721 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
722 break;
723
724 case Bgoto:
14726871 725 MAYBE_GC ();
e12ea64e 726 BYTE_CODE_QUIT;
36f7ba0a 727 op = FETCH2; /* pc = FETCH2 loses since FETCH2 contains pc++ */
3d5fc37b 728 CHECK_RANGE (op);
7ca1e8b7 729 stack.pc = stack.byte_string_start + op;
36f7ba0a
JB
730 break;
731
36f7ba0a 732 case Bgotoifnonnil:
21ed6de3
KR
733 {
734 Lisp_Object v1;
735 MAYBE_GC ();
736 op = FETCH2;
737 v1 = POP;
738 if (!NILP (v1))
739 {
740 BYTE_CODE_QUIT;
741 CHECK_RANGE (op);
742 stack.pc = stack.byte_string_start + op;
743 }
744 break;
745 }
36f7ba0a
JB
746
747 case Bgotoifnilelsepop:
14726871 748 MAYBE_GC ();
36f7ba0a 749 op = FETCH2;
921a8935 750 if (NILP (TOP))
36f7ba0a 751 {
e12ea64e 752 BYTE_CODE_QUIT;
3d5fc37b 753 CHECK_RANGE (op);
7ca1e8b7 754 stack.pc = stack.byte_string_start + op;
36f7ba0a 755 }
63639d44 756 else DISCARD (1);
36f7ba0a
JB
757 break;
758
759 case Bgotoifnonnilelsepop:
14726871 760 MAYBE_GC ();
36f7ba0a 761 op = FETCH2;
921a8935 762 if (!NILP (TOP))
36f7ba0a 763 {
e12ea64e 764 BYTE_CODE_QUIT;
3d5fc37b 765 CHECK_RANGE (op);
7ca1e8b7 766 stack.pc = stack.byte_string_start + op;
36f7ba0a 767 }
63639d44
JB
768 else DISCARD (1);
769 break;
770
771 case BRgoto:
14726871 772 MAYBE_GC ();
e12ea64e 773 BYTE_CODE_QUIT;
7ca1e8b7 774 stack.pc += (int) *stack.pc - 127;
63639d44
JB
775 break;
776
777 case BRgotoifnil:
21ed6de3
KR
778 {
779 Lisp_Object v1;
780 MAYBE_GC ();
781 v1 = POP;
782 if (NILP (v1))
783 {
784 BYTE_CODE_QUIT;
785 stack.pc += (int) *stack.pc - 128;
786 }
787 stack.pc++;
788 break;
789 }
63639d44
JB
790
791 case BRgotoifnonnil:
21ed6de3
KR
792 {
793 Lisp_Object v1;
794 MAYBE_GC ();
795 v1 = POP;
796 if (!NILP (v1))
797 {
798 BYTE_CODE_QUIT;
799 stack.pc += (int) *stack.pc - 128;
800 }
801 stack.pc++;
802 break;
803 }
63639d44
JB
804
805 case BRgotoifnilelsepop:
14726871 806 MAYBE_GC ();
7ca1e8b7 807 op = *stack.pc++;
63639d44
JB
808 if (NILP (TOP))
809 {
e12ea64e 810 BYTE_CODE_QUIT;
7ca1e8b7 811 stack.pc += op - 128;
63639d44
JB
812 }
813 else DISCARD (1);
814 break;
815
816 case BRgotoifnonnilelsepop:
14726871 817 MAYBE_GC ();
7ca1e8b7 818 op = *stack.pc++;
63639d44
JB
819 if (!NILP (TOP))
820 {
e12ea64e 821 BYTE_CODE_QUIT;
7ca1e8b7 822 stack.pc += op - 128;
63639d44
JB
823 }
824 else DISCARD (1);
98bf0c8d
JB
825 break;
826
36f7ba0a 827 case Breturn:
4015b3c0 828 result = POP;
36f7ba0a
JB
829 goto exit;
830
831 case Bdiscard:
63639d44 832 DISCARD (1);
36f7ba0a
JB
833 break;
834
36f7ba0a
JB
835 case Bconstant2:
836 PUSH (vectorp[FETCH2]);
837 break;
838
839 case Bsave_excursion:
fa9aabf6
GM
840 record_unwind_protect (save_excursion_restore,
841 save_excursion_save ());
36f7ba0a
JB
842 break;
843
3b841abc 844 case Bsave_current_buffer:
80402f25 845 case Bsave_current_buffer_1:
de404585 846 record_unwind_protect (set_buffer_if_live, Fcurrent_buffer ());
3b841abc
RS
847 break;
848
36f7ba0a 849 case Bsave_window_excursion:
4015b3c0 850 BEFORE_POTENTIAL_GC ();
36f7ba0a 851 TOP = Fsave_window_excursion (TOP);
4015b3c0 852 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
853 break;
854
855 case Bsave_restriction:
fa9aabf6
GM
856 record_unwind_protect (save_restriction_restore,
857 save_restriction_save ());
36f7ba0a
JB
858 break;
859
860 case Bcatch:
4015b3c0
GM
861 {
862 Lisp_Object v1;
4015b3c0 863 BEFORE_POTENTIAL_GC ();
bf1de43e 864 v1 = POP;
4015b3c0
GM
865 TOP = internal_catch (TOP, Feval, v1);
866 AFTER_POTENTIAL_GC ();
867 break;
868 }
36f7ba0a
JB
869
870 case Bunwind_protect:
ba3fb063 871 record_unwind_protect (Fprogn, POP);
36f7ba0a
JB
872 break;
873
874 case Bcondition_case:
4015b3c0 875 {
5c125a13
RS
876 Lisp_Object handlers, body;
877 handlers = POP;
878 body = POP;
4015b3c0 879 BEFORE_POTENTIAL_GC ();
5c125a13 880 TOP = internal_lisp_condition_case (TOP, body, handlers);
4015b3c0
GM
881 AFTER_POTENTIAL_GC ();
882 break;
883 }
36f7ba0a
JB
884
885 case Btemp_output_buffer_setup:
4015b3c0 886 BEFORE_POTENTIAL_GC ();
b7826503 887 CHECK_STRING (TOP);
42a5b22f 888 temp_output_buffer_setup (SSDATA (TOP));
4015b3c0 889 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
890 TOP = Vstandard_output;
891 break;
892
893 case Btemp_output_buffer_show:
4015b3c0
GM
894 {
895 Lisp_Object v1;
4015b3c0 896 BEFORE_POTENTIAL_GC ();
bf1de43e 897 v1 = POP;
4015b3c0
GM
898 temp_output_buffer_show (TOP);
899 TOP = v1;
900 /* pop binding of standard-output */
aed13378 901 unbind_to (SPECPDL_INDEX () - 1, Qnil);
4015b3c0
GM
902 AFTER_POTENTIAL_GC ();
903 break;
904 }
36f7ba0a
JB
905
906 case Bnth:
4015b3c0
GM
907 {
908 Lisp_Object v1, v2;
bf1de43e 909 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
910 v1 = POP;
911 v2 = TOP;
b7826503 912 CHECK_NUMBER (v2);
f5941bf8 913 AFTER_POTENTIAL_GC ();
4015b3c0
GM
914 op = XINT (v2);
915 immediate_quit = 1;
14c5155a
KS
916 while (--op >= 0 && CONSP (v1))
917 v1 = XCDR (v1);
4015b3c0 918 immediate_quit = 0;
14c5155a 919 TOP = CAR (v1);
4015b3c0
GM
920 break;
921 }
36f7ba0a
JB
922
923 case Bsymbolp:
617bd3f6 924 TOP = SYMBOLP (TOP) ? Qt : Qnil;
36f7ba0a
JB
925 break;
926
927 case Bconsp:
928 TOP = CONSP (TOP) ? Qt : Qnil;
929 break;
930
931 case Bstringp:
617bd3f6 932 TOP = STRINGP (TOP) ? Qt : Qnil;
36f7ba0a
JB
933 break;
934
935 case Blistp:
921a8935 936 TOP = CONSP (TOP) || NILP (TOP) ? Qt : Qnil;
36f7ba0a
JB
937 break;
938
36f7ba0a 939 case Bnot:
921a8935 940 TOP = NILP (TOP) ? Qt : Qnil;
36f7ba0a
JB
941 break;
942
36f7ba0a 943 case Bcons:
4015b3c0
GM
944 {
945 Lisp_Object v1;
946 v1 = POP;
947 TOP = Fcons (TOP, v1);
948 break;
949 }
36f7ba0a
JB
950
951 case Blist1:
952 TOP = Fcons (TOP, Qnil);
953 break;
954
955 case Blist2:
4015b3c0
GM
956 {
957 Lisp_Object v1;
958 v1 = POP;
959 TOP = Fcons (TOP, Fcons (v1, Qnil));
960 break;
961 }
36f7ba0a
JB
962
963 case Blist3:
63639d44 964 DISCARD (2);
36f7ba0a
JB
965 TOP = Flist (3, &TOP);
966 break;
967
968 case Blist4:
63639d44 969 DISCARD (3);
36f7ba0a
JB
970 TOP = Flist (4, &TOP);
971 break;
972
63639d44
JB
973 case BlistN:
974 op = FETCH;
975 DISCARD (op - 1);
976 TOP = Flist (op, &TOP);
977 break;
978
36f7ba0a 979 case Blength:
bf1de43e 980 BEFORE_POTENTIAL_GC ();
36f7ba0a 981 TOP = Flength (TOP);
bf1de43e 982 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
983 break;
984
985 case Baref:
4015b3c0
GM
986 {
987 Lisp_Object v1;
bf1de43e 988 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
989 v1 = POP;
990 TOP = Faref (TOP, v1);
bf1de43e 991 AFTER_POTENTIAL_GC ();
4015b3c0
GM
992 break;
993 }
36f7ba0a
JB
994
995 case Baset:
4015b3c0
GM
996 {
997 Lisp_Object v1, v2;
bf1de43e 998 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
999 v2 = POP; v1 = POP;
1000 TOP = Faset (TOP, v1, v2);
bf1de43e 1001 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1002 break;
1003 }
36f7ba0a
JB
1004
1005 case Bsymbol_value:
bf1de43e 1006 BEFORE_POTENTIAL_GC ();
36f7ba0a 1007 TOP = Fsymbol_value (TOP);
bf1de43e 1008 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1009 break;
1010
1011 case Bsymbol_function:
bf1de43e 1012 BEFORE_POTENTIAL_GC ();
36f7ba0a 1013 TOP = Fsymbol_function (TOP);
bf1de43e 1014 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1015 break;
1016
1017 case Bset:
4015b3c0
GM
1018 {
1019 Lisp_Object v1;
bf1de43e 1020 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1021 v1 = POP;
1022 TOP = Fset (TOP, v1);
bf1de43e 1023 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1024 break;
1025 }
36f7ba0a
JB
1026
1027 case Bfset:
4015b3c0
GM
1028 {
1029 Lisp_Object v1;
bf1de43e 1030 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1031 v1 = POP;
1032 TOP = Ffset (TOP, v1);
bf1de43e 1033 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1034 break;
1035 }
36f7ba0a
JB
1036
1037 case Bget:
4015b3c0
GM
1038 {
1039 Lisp_Object v1;
bf1de43e 1040 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1041 v1 = POP;
1042 TOP = Fget (TOP, v1);
bf1de43e 1043 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1044 break;
1045 }
36f7ba0a
JB
1046
1047 case Bsubstring:
4015b3c0
GM
1048 {
1049 Lisp_Object v1, v2;
fa9aabf6 1050 BEFORE_POTENTIAL_GC ();
bf1de43e 1051 v2 = POP; v1 = POP;
4015b3c0 1052 TOP = Fsubstring (TOP, v1, v2);
fa9aabf6 1053 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1054 break;
1055 }
36f7ba0a
JB
1056
1057 case Bconcat2:
bf1de43e 1058 BEFORE_POTENTIAL_GC ();
63639d44 1059 DISCARD (1);
36f7ba0a 1060 TOP = Fconcat (2, &TOP);
bf1de43e 1061 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1062 break;
1063
1064 case Bconcat3:
bf1de43e 1065 BEFORE_POTENTIAL_GC ();
63639d44 1066 DISCARD (2);
36f7ba0a 1067 TOP = Fconcat (3, &TOP);
bf1de43e 1068 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1069 break;
1070
1071 case Bconcat4:
bf1de43e 1072 BEFORE_POTENTIAL_GC ();
63639d44 1073 DISCARD (3);
36f7ba0a 1074 TOP = Fconcat (4, &TOP);
bf1de43e 1075 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1076 break;
1077
63639d44
JB
1078 case BconcatN:
1079 op = FETCH;
bf1de43e 1080 BEFORE_POTENTIAL_GC ();
63639d44
JB
1081 DISCARD (op - 1);
1082 TOP = Fconcat (op, &TOP);
bf1de43e 1083 AFTER_POTENTIAL_GC ();
63639d44
JB
1084 break;
1085
36f7ba0a 1086 case Bsub1:
4015b3c0
GM
1087 {
1088 Lisp_Object v1;
1089 v1 = TOP;
1090 if (INTEGERP (v1))
1091 {
1092 XSETINT (v1, XINT (v1) - 1);
1093 TOP = v1;
1094 }
1095 else
e494eee5
MB
1096 {
1097 BEFORE_POTENTIAL_GC ();
1098 TOP = Fsub1 (v1);
1099 AFTER_POTENTIAL_GC ();
1100 }
4015b3c0
GM
1101 break;
1102 }
36f7ba0a
JB
1103
1104 case Badd1:
4015b3c0
GM
1105 {
1106 Lisp_Object v1;
1107 v1 = TOP;
1108 if (INTEGERP (v1))
1109 {
1110 XSETINT (v1, XINT (v1) + 1);
1111 TOP = v1;
1112 }
1113 else
bf1de43e
GM
1114 {
1115 BEFORE_POTENTIAL_GC ();
1116 TOP = Fadd1 (v1);
1117 AFTER_POTENTIAL_GC ();
1118 }
4015b3c0
GM
1119 break;
1120 }
36f7ba0a
JB
1121
1122 case Beqlsign:
4015b3c0
GM
1123 {
1124 Lisp_Object v1, v2;
f5941bf8 1125 BEFORE_POTENTIAL_GC ();
bf1de43e 1126 v2 = POP; v1 = TOP;
b7826503
PJ
1127 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (v1);
1128 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (v2);
f5941bf8 1129 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1130 if (FLOATP (v1) || FLOATP (v2))
1131 {
1132 double f1, f2;
1133
1134 f1 = (FLOATP (v1) ? XFLOAT_DATA (v1) : XINT (v1));
1135 f2 = (FLOATP (v2) ? XFLOAT_DATA (v2) : XINT (v2));
1136 TOP = (f1 == f2 ? Qt : Qnil);
1137 }
1138 else
4015b3c0
GM
1139 TOP = (XINT (v1) == XINT (v2) ? Qt : Qnil);
1140 break;
1141 }
36f7ba0a
JB
1142
1143 case Bgtr:
4015b3c0
GM
1144 {
1145 Lisp_Object v1;
bf1de43e 1146 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1147 v1 = POP;
1148 TOP = Fgtr (TOP, v1);
bf1de43e 1149 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1150 break;
1151 }
36f7ba0a
JB
1152
1153 case Blss:
4015b3c0
GM
1154 {
1155 Lisp_Object v1;
bf1de43e 1156 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1157 v1 = POP;
1158 TOP = Flss (TOP, v1);
bf1de43e 1159 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1160 break;
1161 }
36f7ba0a
JB
1162
1163 case Bleq:
4015b3c0
GM
1164 {
1165 Lisp_Object v1;
bf1de43e 1166 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1167 v1 = POP;
1168 TOP = Fleq (TOP, v1);
bf1de43e 1169 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1170 break;
1171 }
36f7ba0a
JB
1172
1173 case Bgeq:
4015b3c0
GM
1174 {
1175 Lisp_Object v1;
d9c1f6f9 1176 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1177 v1 = POP;
1178 TOP = Fgeq (TOP, v1);
d9c1f6f9 1179 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1180 break;
1181 }
36f7ba0a
JB
1182
1183 case Bdiff:
bf1de43e 1184 BEFORE_POTENTIAL_GC ();
63639d44 1185 DISCARD (1);
36f7ba0a 1186 TOP = Fminus (2, &TOP);
bf1de43e 1187 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1188 break;
1189
1190 case Bnegate:
4015b3c0
GM
1191 {
1192 Lisp_Object v1;
1193 v1 = TOP;
1194 if (INTEGERP (v1))
1195 {
1196 XSETINT (v1, - XINT (v1));
1197 TOP = v1;
1198 }
1199 else
bf1de43e
GM
1200 {
1201 BEFORE_POTENTIAL_GC ();
1202 TOP = Fminus (1, &TOP);
1203 AFTER_POTENTIAL_GC ();
1204 }
4015b3c0
GM
1205 break;
1206 }
36f7ba0a
JB
1207
1208 case Bplus:
bf1de43e 1209 BEFORE_POTENTIAL_GC ();
63639d44 1210 DISCARD (1);
36f7ba0a 1211 TOP = Fplus (2, &TOP);
bf1de43e 1212 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1213 break;
1214
1215 case Bmax:
bf1de43e 1216 BEFORE_POTENTIAL_GC ();
63639d44 1217 DISCARD (1);
36f7ba0a 1218 TOP = Fmax (2, &TOP);
bf1de43e 1219 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1220 break;
1221
1222 case Bmin:
bf1de43e 1223 BEFORE_POTENTIAL_GC ();
63639d44 1224 DISCARD (1);
36f7ba0a 1225 TOP = Fmin (2, &TOP);
bf1de43e 1226 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1227 break;
1228
1229 case Bmult:
bf1de43e 1230 BEFORE_POTENTIAL_GC ();
63639d44 1231 DISCARD (1);
36f7ba0a 1232 TOP = Ftimes (2, &TOP);
bf1de43e 1233 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1234 break;
1235
1236 case Bquo:
bf1de43e 1237 BEFORE_POTENTIAL_GC ();
63639d44 1238 DISCARD (1);
36f7ba0a 1239 TOP = Fquo (2, &TOP);
bf1de43e 1240 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1241 break;
1242
1243 case Brem:
4015b3c0
GM
1244 {
1245 Lisp_Object v1;
bf1de43e 1246 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1247 v1 = POP;
1248 TOP = Frem (TOP, v1);
bf1de43e 1249 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1250 break;
1251 }
36f7ba0a
JB
1252
1253 case Bpoint:
4015b3c0
GM
1254 {
1255 Lisp_Object v1;
1256 XSETFASTINT (v1, PT);
1257 PUSH (v1);
1258 break;
1259 }
36f7ba0a
JB
1260
1261 case Bgoto_char:
4015b3c0 1262 BEFORE_POTENTIAL_GC ();
36f7ba0a 1263 TOP = Fgoto_char (TOP);
4015b3c0 1264 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1265 break;
1266
1267 case Binsert:
4015b3c0 1268 BEFORE_POTENTIAL_GC ();
36f7ba0a 1269 TOP = Finsert (1, &TOP);
4015b3c0 1270 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1271 break;
1272
63639d44
JB
1273 case BinsertN:
1274 op = FETCH;
4015b3c0 1275 BEFORE_POTENTIAL_GC ();
fa9aabf6 1276 DISCARD (op - 1);
63639d44 1277 TOP = Finsert (op, &TOP);
4015b3c0 1278 AFTER_POTENTIAL_GC ();
63639d44
JB
1279 break;
1280
36f7ba0a 1281 case Bpoint_max:
4015b3c0
GM
1282 {
1283 Lisp_Object v1;
1284 XSETFASTINT (v1, ZV);
1285 PUSH (v1);
1286 break;
1287 }
36f7ba0a
JB
1288
1289 case Bpoint_min:
4015b3c0
GM
1290 {
1291 Lisp_Object v1;
1292 XSETFASTINT (v1, BEGV);
1293 PUSH (v1);
1294 break;
1295 }
36f7ba0a
JB
1296
1297 case Bchar_after:
bf1de43e 1298 BEFORE_POTENTIAL_GC ();
36f7ba0a 1299 TOP = Fchar_after (TOP);
bf1de43e 1300 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1301 break;
1302
1303 case Bfollowing_char:
4015b3c0
GM
1304 {
1305 Lisp_Object v1;
bf1de43e 1306 BEFORE_POTENTIAL_GC ();
4015b3c0 1307 v1 = Ffollowing_char ();
bf1de43e 1308 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1309 PUSH (v1);
1310 break;
1311 }
36f7ba0a
JB
1312
1313 case Bpreceding_char:
4015b3c0
GM
1314 {
1315 Lisp_Object v1;
bf1de43e 1316 BEFORE_POTENTIAL_GC ();
4015b3c0 1317 v1 = Fprevious_char ();
bf1de43e 1318 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1319 PUSH (v1);
1320 break;
1321 }
36f7ba0a
JB
1322
1323 case Bcurrent_column:
4015b3c0
GM
1324 {
1325 Lisp_Object v1;
96111f48 1326 BEFORE_POTENTIAL_GC ();
7831777b 1327 XSETFASTINT (v1, current_column ());
96111f48 1328 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1329 PUSH (v1);
1330 break;
1331 }
36f7ba0a
JB
1332
1333 case Bindent_to:
4015b3c0 1334 BEFORE_POTENTIAL_GC ();
36f7ba0a 1335 TOP = Findent_to (TOP, Qnil);
4015b3c0 1336 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1337 break;
1338
1339 case Beolp:
1340 PUSH (Feolp ());
1341 break;
1342
1343 case Beobp:
1344 PUSH (Feobp ());
1345 break;
1346
1347 case Bbolp:
1348 PUSH (Fbolp ());
1349 break;
1350
1351 case Bbobp:
1352 PUSH (Fbobp ());
1353 break;
1354
1355 case Bcurrent_buffer:
1356 PUSH (Fcurrent_buffer ());
1357 break;
1358
1359 case Bset_buffer:
4015b3c0 1360 BEFORE_POTENTIAL_GC ();
36f7ba0a 1361 TOP = Fset_buffer (TOP);
4015b3c0 1362 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1363 break;
1364
36f7ba0a
JB
1365 case Binteractive_p:
1366 PUSH (Finteractive_p ());
1367 break;
1368
1369 case Bforward_char:
4015b3c0 1370 BEFORE_POTENTIAL_GC ();
36f7ba0a 1371 TOP = Fforward_char (TOP);
4015b3c0 1372 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1373 break;
1374
1375 case Bforward_word:
4015b3c0 1376 BEFORE_POTENTIAL_GC ();
36f7ba0a 1377 TOP = Fforward_word (TOP);
4015b3c0 1378 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1379 break;
1380
1381 case Bskip_chars_forward:
4015b3c0
GM
1382 {
1383 Lisp_Object v1;
4015b3c0 1384 BEFORE_POTENTIAL_GC ();
bf1de43e 1385 v1 = POP;
4015b3c0
GM
1386 TOP = Fskip_chars_forward (TOP, v1);
1387 AFTER_POTENTIAL_GC ();
1388 break;
1389 }
36f7ba0a
JB
1390
1391 case Bskip_chars_backward:
4015b3c0
GM
1392 {
1393 Lisp_Object v1;
4015b3c0 1394 BEFORE_POTENTIAL_GC ();
bf1de43e 1395 v1 = POP;
4015b3c0
GM
1396 TOP = Fskip_chars_backward (TOP, v1);
1397 AFTER_POTENTIAL_GC ();
1398 break;
1399 }
36f7ba0a
JB
1400
1401 case Bforward_line:
4015b3c0 1402 BEFORE_POTENTIAL_GC ();
36f7ba0a 1403 TOP = Fforward_line (TOP);
4015b3c0 1404 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1405 break;
1406
1407 case Bchar_syntax:
9281d077
KH
1408 {
1409 int c;
1410
1411 BEFORE_POTENTIAL_GC ();
1412 CHECK_CHARACTER (TOP);
1413 AFTER_POTENTIAL_GC ();
1414 c = XFASTINT (TOP);
4b4deea2 1415 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
9281d077
KH
1416 MAKE_CHAR_MULTIBYTE (c);
1417 XSETFASTINT (TOP, syntax_code_spec[(int) SYNTAX (c)]);
8f924df7 1418 }
36f7ba0a
JB
1419 break;
1420
1421 case Bbuffer_substring:
4015b3c0
GM
1422 {
1423 Lisp_Object v1;
4015b3c0 1424 BEFORE_POTENTIAL_GC ();
bf1de43e 1425 v1 = POP;
4015b3c0
GM
1426 TOP = Fbuffer_substring (TOP, v1);
1427 AFTER_POTENTIAL_GC ();
1428 break;
1429 }
36f7ba0a
JB
1430
1431 case Bdelete_region:
4015b3c0
GM
1432 {
1433 Lisp_Object v1;
4015b3c0 1434 BEFORE_POTENTIAL_GC ();
bf1de43e 1435 v1 = POP;
4015b3c0
GM
1436 TOP = Fdelete_region (TOP, v1);
1437 AFTER_POTENTIAL_GC ();
1438 break;
1439 }
36f7ba0a
JB
1440
1441 case Bnarrow_to_region:
4015b3c0
GM
1442 {
1443 Lisp_Object v1;
4015b3c0 1444 BEFORE_POTENTIAL_GC ();
bf1de43e 1445 v1 = POP;
4015b3c0
GM
1446 TOP = Fnarrow_to_region (TOP, v1);
1447 AFTER_POTENTIAL_GC ();
1448 break;
1449 }
36f7ba0a
JB
1450
1451 case Bwiden:
4015b3c0 1452 BEFORE_POTENTIAL_GC ();
36f7ba0a 1453 PUSH (Fwiden ());
4015b3c0 1454 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1455 break;
1456
63639d44 1457 case Bend_of_line:
4015b3c0 1458 BEFORE_POTENTIAL_GC ();
63639d44 1459 TOP = Fend_of_line (TOP);
4015b3c0 1460 AFTER_POTENTIAL_GC ();
63639d44
JB
1461 break;
1462
1463 case Bset_marker:
4015b3c0
GM
1464 {
1465 Lisp_Object v1, v2;
bf1de43e 1466 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1467 v1 = POP;
1468 v2 = POP;
1469 TOP = Fset_marker (TOP, v2, v1);
bf1de43e 1470 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1471 break;
1472 }
63639d44
JB
1473
1474 case Bmatch_beginning:
bf1de43e 1475 BEFORE_POTENTIAL_GC ();
63639d44 1476 TOP = Fmatch_beginning (TOP);
bf1de43e 1477 AFTER_POTENTIAL_GC ();
63639d44
JB
1478 break;
1479
1480 case Bmatch_end:
bf1de43e 1481 BEFORE_POTENTIAL_GC ();
63639d44 1482 TOP = Fmatch_end (TOP);
bf1de43e 1483 AFTER_POTENTIAL_GC ();
63639d44
JB
1484 break;
1485
1486 case Bupcase:
bf1de43e 1487 BEFORE_POTENTIAL_GC ();
63639d44 1488 TOP = Fupcase (TOP);
bf1de43e 1489 AFTER_POTENTIAL_GC ();
63639d44
JB
1490 break;
1491
1492 case Bdowncase:
bf1de43e 1493 BEFORE_POTENTIAL_GC ();
63639d44 1494 TOP = Fdowncase (TOP);
bf1de43e 1495 AFTER_POTENTIAL_GC ();
63639d44
JB
1496 break;
1497
36f7ba0a 1498 case Bstringeqlsign:
4015b3c0
GM
1499 {
1500 Lisp_Object v1;
bf1de43e 1501 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1502 v1 = POP;
1503 TOP = Fstring_equal (TOP, v1);
bf1de43e 1504 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1505 break;
1506 }
36f7ba0a
JB
1507
1508 case Bstringlss:
4015b3c0
GM
1509 {
1510 Lisp_Object v1;
bf1de43e 1511 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1512 v1 = POP;
1513 TOP = Fstring_lessp (TOP, v1);
bf1de43e 1514 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1515 break;
1516 }
36f7ba0a
JB
1517
1518 case Bequal:
4015b3c0
GM
1519 {
1520 Lisp_Object v1;
1521 v1 = POP;
1522 TOP = Fequal (TOP, v1);
1523 break;
1524 }
36f7ba0a
JB
1525
1526 case Bnthcdr:
4015b3c0
GM
1527 {
1528 Lisp_Object v1;
bf1de43e 1529 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1530 v1 = POP;
1531 TOP = Fnthcdr (TOP, v1);
bf1de43e 1532 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1533 break;
1534 }
36f7ba0a
JB
1535
1536 case Belt:
4015b3c0
GM
1537 {
1538 Lisp_Object v1, v2;
1539 if (CONSP (TOP))
1540 {
1541 /* Exchange args and then do nth. */
bf1de43e 1542 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1543 v2 = POP;
1544 v1 = TOP;
b7826503 1545 CHECK_NUMBER (v2);
f5941bf8 1546 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1547 op = XINT (v2);
1548 immediate_quit = 1;
14c5155a
KS
1549 while (--op >= 0 && CONSP (v1))
1550 v1 = XCDR (v1);
4015b3c0 1551 immediate_quit = 0;
14c5155a 1552 TOP = CAR (v1);
4015b3c0
GM
1553 }
1554 else
1555 {
bf1de43e 1556 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1557 v1 = POP;
1558 TOP = Felt (TOP, v1);
bf1de43e 1559 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1560 }
1561 break;
1562 }
36f7ba0a
JB
1563
1564 case Bmember:
4015b3c0
GM
1565 {
1566 Lisp_Object v1;
bf1de43e 1567 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1568 v1 = POP;
1569 TOP = Fmember (TOP, v1);
bf1de43e 1570 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1571 break;
1572 }
36f7ba0a
JB
1573
1574 case Bassq:
4015b3c0
GM
1575 {
1576 Lisp_Object v1;
bf1de43e 1577 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1578 v1 = POP;
1579 TOP = Fassq (TOP, v1);
bf1de43e 1580 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1581 break;
1582 }
36f7ba0a
JB
1583
1584 case Bnreverse:
bf1de43e 1585 BEFORE_POTENTIAL_GC ();
36f7ba0a 1586 TOP = Fnreverse (TOP);
bf1de43e 1587 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1588 break;
1589
1590 case Bsetcar:
4015b3c0
GM
1591 {
1592 Lisp_Object v1;
bf1de43e 1593 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1594 v1 = POP;
1595 TOP = Fsetcar (TOP, v1);
bf1de43e 1596 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1597 break;
1598 }
36f7ba0a
JB
1599
1600 case Bsetcdr:
4015b3c0
GM
1601 {
1602 Lisp_Object v1;
bf1de43e 1603 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1604 v1 = POP;
1605 TOP = Fsetcdr (TOP, v1);
bf1de43e 1606 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1607 break;
1608 }
36f7ba0a
JB
1609
1610 case Bcar_safe:
4015b3c0
GM
1611 {
1612 Lisp_Object v1;
1613 v1 = TOP;
14c5155a 1614 TOP = CAR_SAFE (v1);
4015b3c0
GM
1615 break;
1616 }
36f7ba0a
JB
1617
1618 case Bcdr_safe:
4015b3c0
GM
1619 {
1620 Lisp_Object v1;
1621 v1 = TOP;
14c5155a 1622 TOP = CDR_SAFE (v1);
4015b3c0
GM
1623 break;
1624 }
36f7ba0a
JB
1625
1626 case Bnconc:
bf1de43e 1627 BEFORE_POTENTIAL_GC ();
63639d44 1628 DISCARD (1);
36f7ba0a 1629 TOP = Fnconc (2, &TOP);
bf1de43e 1630 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1631 break;
1632
1633 case Bnumberp:
63639d44 1634 TOP = (NUMBERP (TOP) ? Qt : Qnil);
36f7ba0a
JB
1635 break;
1636
1637 case Bintegerp:
617bd3f6 1638 TOP = INTEGERP (TOP) ? Qt : Qnil;
36f7ba0a
JB
1639 break;
1640
1641#ifdef BYTE_CODE_SAFE
1642 case Bset_mark:
f5941bf8 1643 BEFORE_POTENTIAL_GC ();
36f7ba0a 1644 error ("set-mark is an obsolete bytecode");
f5941bf8 1645 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1646 break;
1647 case Bscan_buffer:
f5941bf8 1648 BEFORE_POTENTIAL_GC ();
36f7ba0a 1649 error ("scan-buffer is an obsolete bytecode");
f5941bf8 1650 AFTER_POTENTIAL_GC ();
36f7ba0a 1651 break;
36f7ba0a
JB
1652#endif
1653
c96d71f7
RS
1654 case 0:
1655 abort ();
1656
1657 case 255:
36f7ba0a
JB
1658 default:
1659#ifdef BYTE_CODE_SAFE
1660 if (op < Bconstant)
f5941bf8 1661 {
cc94f3b2 1662 abort ();
f5941bf8 1663 }
36f7ba0a 1664 if ((op -= Bconstant) >= const_length)
f5941bf8 1665 {
cc94f3b2 1666 abort ();
f5941bf8 1667 }
36f7ba0a
JB
1668 PUSH (vectorp[op]);
1669#else
1670 PUSH (vectorp[op - Bconstant]);
1671#endif
1672 }
1673 }
1674
1675 exit:
7ca1e8b7
GM
1676
1677 byte_stack_list = byte_stack_list->next;
1678
36f7ba0a 1679 /* Binds and unbinds are supposed to be compiled balanced. */
aed13378 1680 if (SPECPDL_INDEX () != count)
36f7ba0a
JB
1681#ifdef BYTE_CODE_SAFE
1682 error ("binding stack not balanced (serious byte compiler bug)");
1683#else
1684 abort ();
1685#endif
8e11578b 1686
4015b3c0 1687 return result;
36f7ba0a
JB
1688}
1689
dfcf069d 1690void
971de7fb 1691syms_of_bytecode (void)
36f7ba0a 1692{
d67b4f80 1693 Qbytecode = intern_c_string ("byte-code");
36f7ba0a
JB
1694 staticpro (&Qbytecode);
1695
1696 defsubr (&Sbyte_code);
1697
1698#ifdef BYTE_CODE_METER
1699
29208e82 1700 DEFVAR_LISP ("byte-code-meter", Vbyte_code_meter,
39f624fa
PJ
1701 doc: /* A vector of vectors which holds a histogram of byte-code usage.
1702\(aref (aref byte-code-meter 0) CODE) indicates how many times the byte
1703opcode CODE has been executed.
1704\(aref (aref byte-code-meter CODE1) CODE2), where CODE1 is not 0,
1705indicates how many times the byte opcodes CODE1 and CODE2 have been
1706executed in succession. */);
8e11578b 1707
29208e82 1708 DEFVAR_BOOL ("byte-metering-on", byte_metering_on,
39f624fa
PJ
1709 doc: /* If non-nil, keep profiling information on byte code usage.
1710The variable byte-code-meter indicates how often each byte opcode is used.
1711If a symbol has a property named `byte-code-meter' whose value is an
1712integer, it is incremented each time that symbol's function is called. */);
36f7ba0a
JB
1713
1714 byte_metering_on = 0;
63639d44 1715 Vbyte_code_meter = Fmake_vector (make_number (256), make_number (0));
d67b4f80 1716 Qbyte_code_meter = intern_c_string ("byte-code-meter");
63639d44 1717 staticpro (&Qbyte_code_meter);
36f7ba0a
JB
1718 {
1719 int i = 256;
1720 while (i--)
63639d44
JB
1721 XVECTOR (Vbyte_code_meter)->contents[i] =
1722 Fmake_vector (make_number (256), make_number (0));
36f7ba0a
JB
1723 }
1724#endif
1725}