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