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