(CHECK_CATEGORY, CHECK_CATEGORY_SET): Use CHECK_TYPE.
[bpt/emacs.git] / src / bytecode.c
CommitLineData
36f7ba0a 1/* Execution of byte code produced by bytecomp.el.
0b5538bd 2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 2000, 2001, 2002, 2003, 2004,
aaef169d 3 2005, 2006 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
4fc5845f
LK
19the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20Boston, MA 02110-1301, 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"
9192a027 40#include "charset.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. */
2a1c1d71 289 eassert (stack->top);
8e11578b 290
7ca1e8b7 291 for (obj = stack->bottom; obj <= stack->top; ++obj)
2a1c1d71 292 mark_object (*obj);
a719d13e 293
2a1c1d71
SM
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
3414f2d8
RS
358#define MAYBE_GC() \
359 if (consing_since_gc > gc_cons_threshold \
360 && consing_since_gc > gc_relative_threshold) \
361 { \
362 BEFORE_POTENTIAL_GC (); \
363 Fgarbage_collect (); \
364 AFTER_POTENTIAL_GC (); \
365 } \
5e7ed093
RS
366 else
367
3d5fc37b 368/* Check for jumping out of range. */
7ca1e8b7
GM
369
370#ifdef BYTE_CODE_SAFE
371
4015b3c0 372#define CHECK_RANGE(ARG) \
3d5fc37b
RS
373 if (ARG >= bytestr_length) abort ()
374
4015b3c0 375#else /* not BYTE_CODE_SAFE */
7ca1e8b7
GM
376
377#define CHECK_RANGE(ARG)
378
4015b3c0 379#endif /* not BYTE_CODE_SAFE */
7ca1e8b7 380
e12ea64e
GM
381/* A version of the QUIT macro which makes sure that the stack top is
382 set before signaling `quit'. */
383
384#define BYTE_CODE_QUIT \
385 do { \
386 if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \
387 { \
731475e7 388 Lisp_Object flag = Vquit_flag; \
e12ea64e
GM
389 Vquit_flag = Qnil; \
390 BEFORE_POTENTIAL_GC (); \
731475e7 391 if (EQ (Vthrow_on_input, flag)) \
a8f0f551 392 Fthrow (Vthrow_on_input, Qt); \
e12ea64e 393 Fsignal (Qquit, Qnil); \
892a8eb5 394 AFTER_POTENTIAL_GC (); \
e12ea64e
GM
395 } \
396 } while (0)
397
7ca1e8b7 398
36f7ba0a 399DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0,
39f624fa
PJ
400 doc: /* Function used internally in byte-compiled code.
401The first argument, BYTESTR, is a string of byte code;
402the second, VECTOR, a vector of constants;
403the third, MAXDEPTH, the maximum stack depth used in this function.
404If the third argument is incorrect, Emacs may crash. */)
405 (bytestr, vector, maxdepth)
36f7ba0a
JB
406 Lisp_Object bytestr, vector, maxdepth;
407{
aed13378 408 int count = SPECPDL_INDEX ();
36f7ba0a
JB
409#ifdef BYTE_CODE_METER
410 int this_op = 0;
411 int prev_op;
412#endif
7ca1e8b7 413 int op;
4015b3c0 414 /* Lisp_Object v1, v2; */
089b985f 415 Lisp_Object *vectorp;
36f7ba0a 416#ifdef BYTE_CODE_SAFE
7ca1e8b7
GM
417 int const_length = XVECTOR (vector)->size;
418 Lisp_Object *stacke;
36f7ba0a 419#endif
089b985f 420 int bytestr_length;
7ca1e8b7
GM
421 struct byte_stack stack;
422 Lisp_Object *top;
4015b3c0 423 Lisp_Object result;
36f7ba0a 424
ad7de7d7
GM
425#ifdef CHECK_FRAME_FONT
426 {
427 struct frame *f = SELECTED_FRAME ();
428 if (FRAME_X_P (f)
429 && FRAME_FONT (f)->direction != 0
430 && FRAME_FONT (f)->direction != 1)
431 abort ();
432 }
433#endif
434
b7826503 435 CHECK_STRING (bytestr);
617bd3f6 436 if (!VECTORP (vector))
36f7ba0a 437 vector = wrong_type_argument (Qvectorp, vector);
b7826503 438 CHECK_NUMBER (maxdepth);
36f7ba0a 439
089b985f
KH
440 if (STRING_MULTIBYTE (bytestr))
441 /* BYTESTR must have been produced by Emacs 20.2 or the earlier
442 because they produced a raw 8-bit string for byte-code and now
443 such a byte-code string is loaded as multibyte while raw 8-bit
444 characters converted to multibyte form. Thus, now we must
fbd98f82 445 convert them back to the originally intended unibyte form. */
5274126b 446 bytestr = Fstring_as_unibyte (bytestr);
089b985f 447
d5db4077 448 bytestr_length = SBYTES (bytestr);
089b985f
KH
449 vectorp = XVECTOR (vector)->contents;
450
7ca1e8b7 451 stack.byte_string = bytestr;
d5db4077 452 stack.pc = stack.byte_string_start = SDATA (bytestr);
7ca1e8b7 453 stack.constants = vector;
8e11578b 454 stack.bottom = (Lisp_Object *) alloca (XFASTINT (maxdepth)
7ca1e8b7
GM
455 * sizeof (Lisp_Object));
456 top = stack.bottom - 1;
457 stack.top = NULL;
458 stack.next = byte_stack_list;
459 byte_stack_list = &stack;
36f7ba0a 460
7ca1e8b7
GM
461#ifdef BYTE_CODE_SAFE
462 stacke = stack.bottom - 1 + XFASTINT (maxdepth);
463#endif
8e11578b 464
36f7ba0a
JB
465 while (1)
466 {
467#ifdef BYTE_CODE_SAFE
9e49c990 468 if (top > stacke)
cc94f3b2 469 abort ();
7ca1e8b7 470 else if (top < stack.bottom - 1)
cc94f3b2 471 abort ();
36f7ba0a
JB
472#endif
473
36f7ba0a
JB
474#ifdef BYTE_CODE_METER
475 prev_op = this_op;
476 this_op = op = FETCH;
477 METER_CODE (prev_op, op);
36f7ba0a 478#else
4015b3c0 479 op = FETCH;
36f7ba0a 480#endif
36f7ba0a 481
4015b3c0
GM
482 switch (op)
483 {
484 case Bvarref + 7:
36f7ba0a
JB
485 op = FETCH2;
486 goto varref;
487
8e11578b
TTN
488 case Bvarref:
489 case Bvarref + 1:
490 case Bvarref + 2:
4015b3c0 491 case Bvarref + 3:
8e11578b 492 case Bvarref + 4:
4015b3c0 493 case Bvarref + 5:
36f7ba0a 494 op = op - Bvarref;
4015b3c0
GM
495 goto varref;
496
497 /* This seems to be the most frequently executed byte-code
498 among the Bvarref's, so avoid a goto here. */
499 case Bvarref+6:
500 op = FETCH;
36f7ba0a 501 varref:
4015b3c0
GM
502 {
503 Lisp_Object v1, v2;
504
505 v1 = vectorp[op];
506 if (SYMBOLP (v1))
507 {
5133a578 508 v2 = SYMBOL_VALUE (v1);
4015b3c0 509 if (MISCP (v2) || EQ (v2, Qunbound))
bf1de43e
GM
510 {
511 BEFORE_POTENTIAL_GC ();
512 v2 = Fsymbol_value (v1);
513 AFTER_POTENTIAL_GC ();
514 }
4015b3c0
GM
515 }
516 else
bf1de43e
GM
517 {
518 BEFORE_POTENTIAL_GC ();
519 v2 = Fsymbol_value (v1);
520 AFTER_POTENTIAL_GC ();
521 }
4015b3c0
GM
522 PUSH (v2);
523 break;
524 }
525
526 case Bgotoifnil:
21ed6de3
KR
527 {
528 Lisp_Object v1;
529 MAYBE_GC ();
530 op = FETCH2;
531 v1 = POP;
532 if (NILP (v1))
533 {
534 BYTE_CODE_QUIT;
535 CHECK_RANGE (op);
536 stack.pc = stack.byte_string_start + op;
537 }
538 break;
539 }
36f7ba0a 540
4015b3c0
GM
541 case Bcar:
542 {
543 Lisp_Object v1;
544 v1 = TOP;
fa9aabf6
GM
545 if (CONSP (v1))
546 TOP = XCAR (v1);
547 else if (NILP (v1))
548 TOP = Qnil;
549 else
f5941bf8 550 {
892a8eb5 551 wrong_type_argument (Qlistp, v1);
f5941bf8 552 }
4015b3c0
GM
553 break;
554 }
555
556 case Beq:
557 {
558 Lisp_Object v1;
559 v1 = POP;
560 TOP = EQ (v1, TOP) ? Qt : Qnil;
561 break;
562 }
563
564 case Bmemq:
565 {
566 Lisp_Object v1;
bf1de43e 567 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
568 v1 = POP;
569 TOP = Fmemq (TOP, v1);
bf1de43e 570 AFTER_POTENTIAL_GC ();
4015b3c0
GM
571 break;
572 }
573
574 case Bcdr:
575 {
576 Lisp_Object v1;
577 v1 = TOP;
fa9aabf6
GM
578 if (CONSP (v1))
579 TOP = XCDR (v1);
580 else if (NILP (v1))
581 TOP = Qnil;
582 else
f5941bf8 583 {
892a8eb5 584 wrong_type_argument (Qlistp, v1);
f5941bf8 585 }
4015b3c0
GM
586 break;
587 }
36f7ba0a 588
620cc5fa
GM
589 case Bvarset:
590 case Bvarset+1:
591 case Bvarset+2:
592 case Bvarset+3:
593 case Bvarset+4:
594 case Bvarset+5:
595 op -= Bvarset;
36f7ba0a
JB
596 goto varset;
597
620cc5fa
GM
598 case Bvarset+7:
599 op = FETCH2;
4015b3c0
GM
600 goto varset;
601
602 case Bvarset+6:
603 op = FETCH;
36f7ba0a 604 varset:
620cc5fa
GM
605 {
606 Lisp_Object sym, val;
8e11578b 607
620cc5fa 608 sym = vectorp[op];
bf1de43e 609 val = TOP;
620cc5fa
GM
610
611 /* Inline the most common case. */
612 if (SYMBOLP (sym)
613 && !EQ (val, Qunbound)
5133a578
GM
614 && !XSYMBOL (sym)->indirect_variable
615 && !XSYMBOL (sym)->constant
616 && !MISCP (XSYMBOL (sym)->value))
620cc5fa
GM
617 XSYMBOL (sym)->value = val;
618 else
bf1de43e
GM
619 {
620 BEFORE_POTENTIAL_GC ();
621 set_internal (sym, val, current_buffer, 0);
622 AFTER_POTENTIAL_GC ();
623 }
620cc5fa 624 }
3789dcdf 625 (void) POP;
36f7ba0a
JB
626 break;
627
4015b3c0
GM
628 case Bdup:
629 {
630 Lisp_Object v1;
631 v1 = TOP;
632 PUSH (v1);
633 break;
634 }
635
636 /* ------------------ */
637
36f7ba0a
JB
638 case Bvarbind+6:
639 op = FETCH;
640 goto varbind;
641
642 case Bvarbind+7:
643 op = FETCH2;
644 goto varbind;
645
fa9aabf6
GM
646 case Bvarbind:
647 case Bvarbind+1:
648 case Bvarbind+2:
649 case Bvarbind+3:
650 case Bvarbind+4:
651 case Bvarbind+5:
36f7ba0a
JB
652 op -= Bvarbind;
653 varbind:
56b8eef5
GM
654 /* Specbind can signal and thus GC. */
655 BEFORE_POTENTIAL_GC ();
36f7ba0a 656 specbind (vectorp[op], POP);
56b8eef5 657 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
658 break;
659
660 case Bcall+6:
661 op = FETCH;
662 goto docall;
663
664 case Bcall+7:
665 op = FETCH2;
666 goto docall;
667
fa9aabf6
GM
668 case Bcall:
669 case Bcall+1:
670 case Bcall+2:
671 case Bcall+3:
672 case Bcall+4:
673 case Bcall+5:
36f7ba0a
JB
674 op -= Bcall;
675 docall:
4015b3c0 676 {
fa9aabf6 677 BEFORE_POTENTIAL_GC ();
4015b3c0 678 DISCARD (op);
63639d44 679#ifdef BYTE_CODE_METER
4015b3c0
GM
680 if (byte_metering_on && SYMBOLP (TOP))
681 {
682 Lisp_Object v1, v2;
683
684 v1 = TOP;
685 v2 = Fget (v1, Qbyte_code_meter);
686 if (INTEGERP (v2)
f28e6371 687 && XINT (v2) < MOST_POSITIVE_FIXNUM)
4015b3c0
GM
688 {
689 XSETINT (v2, XINT (v2) + 1);
690 Fput (v1, Qbyte_code_meter, v2);
691 }
692 }
63639d44 693#endif
4015b3c0
GM
694 TOP = Ffuncall (op + 1, &TOP);
695 AFTER_POTENTIAL_GC ();
696 break;
697 }
36f7ba0a
JB
698
699 case Bunbind+6:
700 op = FETCH;
701 goto dounbind;
702
703 case Bunbind+7:
704 op = FETCH2;
705 goto dounbind;
706
fa9aabf6
GM
707 case Bunbind:
708 case Bunbind+1:
709 case Bunbind+2:
710 case Bunbind+3:
711 case Bunbind+4:
712 case Bunbind+5:
36f7ba0a
JB
713 op -= Bunbind;
714 dounbind:
7ca1e8b7 715 BEFORE_POTENTIAL_GC ();
aed13378 716 unbind_to (SPECPDL_INDEX () - op, Qnil);
7ca1e8b7 717 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
718 break;
719
720 case Bunbind_all:
721 /* To unbind back to the beginning of this frame. Not used yet,
63639d44 722 but will be needed for tail-recursion elimination. */
7ca1e8b7 723 BEFORE_POTENTIAL_GC ();
36f7ba0a 724 unbind_to (count, Qnil);
7ca1e8b7 725 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
726 break;
727
728 case Bgoto:
14726871 729 MAYBE_GC ();
e12ea64e 730 BYTE_CODE_QUIT;
36f7ba0a 731 op = FETCH2; /* pc = FETCH2 loses since FETCH2 contains pc++ */
3d5fc37b 732 CHECK_RANGE (op);
7ca1e8b7 733 stack.pc = stack.byte_string_start + op;
36f7ba0a
JB
734 break;
735
36f7ba0a 736 case Bgotoifnonnil:
21ed6de3
KR
737 {
738 Lisp_Object v1;
739 MAYBE_GC ();
740 op = FETCH2;
741 v1 = POP;
742 if (!NILP (v1))
743 {
744 BYTE_CODE_QUIT;
745 CHECK_RANGE (op);
746 stack.pc = stack.byte_string_start + op;
747 }
748 break;
749 }
36f7ba0a
JB
750
751 case Bgotoifnilelsepop:
14726871 752 MAYBE_GC ();
36f7ba0a 753 op = FETCH2;
921a8935 754 if (NILP (TOP))
36f7ba0a 755 {
e12ea64e 756 BYTE_CODE_QUIT;
3d5fc37b 757 CHECK_RANGE (op);
7ca1e8b7 758 stack.pc = stack.byte_string_start + op;
36f7ba0a 759 }
63639d44 760 else DISCARD (1);
36f7ba0a
JB
761 break;
762
763 case Bgotoifnonnilelsepop:
14726871 764 MAYBE_GC ();
36f7ba0a 765 op = FETCH2;
921a8935 766 if (!NILP (TOP))
36f7ba0a 767 {
e12ea64e 768 BYTE_CODE_QUIT;
3d5fc37b 769 CHECK_RANGE (op);
7ca1e8b7 770 stack.pc = stack.byte_string_start + op;
36f7ba0a 771 }
63639d44
JB
772 else DISCARD (1);
773 break;
774
775 case BRgoto:
14726871 776 MAYBE_GC ();
e12ea64e 777 BYTE_CODE_QUIT;
7ca1e8b7 778 stack.pc += (int) *stack.pc - 127;
63639d44
JB
779 break;
780
781 case BRgotoifnil:
21ed6de3
KR
782 {
783 Lisp_Object v1;
784 MAYBE_GC ();
785 v1 = POP;
786 if (NILP (v1))
787 {
788 BYTE_CODE_QUIT;
789 stack.pc += (int) *stack.pc - 128;
790 }
791 stack.pc++;
792 break;
793 }
63639d44
JB
794
795 case BRgotoifnonnil:
21ed6de3
KR
796 {
797 Lisp_Object v1;
798 MAYBE_GC ();
799 v1 = POP;
800 if (!NILP (v1))
801 {
802 BYTE_CODE_QUIT;
803 stack.pc += (int) *stack.pc - 128;
804 }
805 stack.pc++;
806 break;
807 }
63639d44
JB
808
809 case BRgotoifnilelsepop:
14726871 810 MAYBE_GC ();
7ca1e8b7 811 op = *stack.pc++;
63639d44
JB
812 if (NILP (TOP))
813 {
e12ea64e 814 BYTE_CODE_QUIT;
7ca1e8b7 815 stack.pc += op - 128;
63639d44
JB
816 }
817 else DISCARD (1);
818 break;
819
820 case BRgotoifnonnilelsepop:
14726871 821 MAYBE_GC ();
7ca1e8b7 822 op = *stack.pc++;
63639d44
JB
823 if (!NILP (TOP))
824 {
e12ea64e 825 BYTE_CODE_QUIT;
7ca1e8b7 826 stack.pc += op - 128;
63639d44
JB
827 }
828 else DISCARD (1);
98bf0c8d
JB
829 break;
830
36f7ba0a 831 case Breturn:
4015b3c0 832 result = POP;
36f7ba0a
JB
833 goto exit;
834
835 case Bdiscard:
63639d44 836 DISCARD (1);
36f7ba0a
JB
837 break;
838
36f7ba0a
JB
839 case Bconstant2:
840 PUSH (vectorp[FETCH2]);
841 break;
842
843 case Bsave_excursion:
fa9aabf6
GM
844 record_unwind_protect (save_excursion_restore,
845 save_excursion_save ());
36f7ba0a
JB
846 break;
847
3b841abc 848 case Bsave_current_buffer:
80402f25 849 case Bsave_current_buffer_1:
de404585 850 record_unwind_protect (set_buffer_if_live, Fcurrent_buffer ());
3b841abc
RS
851 break;
852
36f7ba0a 853 case Bsave_window_excursion:
4015b3c0 854 BEFORE_POTENTIAL_GC ();
36f7ba0a 855 TOP = Fsave_window_excursion (TOP);
4015b3c0 856 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
857 break;
858
859 case Bsave_restriction:
fa9aabf6
GM
860 record_unwind_protect (save_restriction_restore,
861 save_restriction_save ());
36f7ba0a
JB
862 break;
863
864 case Bcatch:
4015b3c0
GM
865 {
866 Lisp_Object v1;
4015b3c0 867 BEFORE_POTENTIAL_GC ();
bf1de43e 868 v1 = POP;
4015b3c0
GM
869 TOP = internal_catch (TOP, Feval, v1);
870 AFTER_POTENTIAL_GC ();
871 break;
872 }
36f7ba0a
JB
873
874 case Bunwind_protect:
ba3fb063 875 record_unwind_protect (Fprogn, POP);
36f7ba0a
JB
876 break;
877
878 case Bcondition_case:
4015b3c0 879 {
5c125a13
RS
880 Lisp_Object handlers, body;
881 handlers = POP;
882 body = POP;
4015b3c0 883 BEFORE_POTENTIAL_GC ();
5c125a13 884 TOP = internal_lisp_condition_case (TOP, body, handlers);
4015b3c0
GM
885 AFTER_POTENTIAL_GC ();
886 break;
887 }
36f7ba0a
JB
888
889 case Btemp_output_buffer_setup:
4015b3c0 890 BEFORE_POTENTIAL_GC ();
b7826503 891 CHECK_STRING (TOP);
d5db4077 892 temp_output_buffer_setup (SDATA (TOP));
4015b3c0 893 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
894 TOP = Vstandard_output;
895 break;
896
897 case Btemp_output_buffer_show:
4015b3c0
GM
898 {
899 Lisp_Object v1;
4015b3c0 900 BEFORE_POTENTIAL_GC ();
bf1de43e 901 v1 = POP;
4015b3c0
GM
902 temp_output_buffer_show (TOP);
903 TOP = v1;
904 /* pop binding of standard-output */
aed13378 905 unbind_to (SPECPDL_INDEX () - 1, Qnil);
4015b3c0
GM
906 AFTER_POTENTIAL_GC ();
907 break;
908 }
36f7ba0a
JB
909
910 case Bnth:
4015b3c0
GM
911 {
912 Lisp_Object v1, v2;
bf1de43e 913 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
914 v1 = POP;
915 v2 = TOP;
b7826503 916 CHECK_NUMBER (v2);
f5941bf8 917 AFTER_POTENTIAL_GC ();
4015b3c0
GM
918 op = XINT (v2);
919 immediate_quit = 1;
920 while (--op >= 0)
921 {
922 if (CONSP (v1))
923 v1 = XCDR (v1);
924 else if (!NILP (v1))
925 {
926 immediate_quit = 0;
892a8eb5 927 wrong_type_argument (Qlistp, v1);
4015b3c0
GM
928 }
929 }
930 immediate_quit = 0;
fa9aabf6
GM
931 if (CONSP (v1))
932 TOP = XCAR (v1);
933 else if (NILP (v1))
934 TOP = Qnil;
935 else
892a8eb5 936 wrong_type_argument (Qlistp, v1);
4015b3c0
GM
937 break;
938 }
36f7ba0a
JB
939
940 case Bsymbolp:
617bd3f6 941 TOP = SYMBOLP (TOP) ? Qt : Qnil;
36f7ba0a
JB
942 break;
943
944 case Bconsp:
945 TOP = CONSP (TOP) ? Qt : Qnil;
946 break;
947
948 case Bstringp:
617bd3f6 949 TOP = STRINGP (TOP) ? Qt : Qnil;
36f7ba0a
JB
950 break;
951
952 case Blistp:
921a8935 953 TOP = CONSP (TOP) || NILP (TOP) ? Qt : Qnil;
36f7ba0a
JB
954 break;
955
36f7ba0a 956 case Bnot:
921a8935 957 TOP = NILP (TOP) ? Qt : Qnil;
36f7ba0a
JB
958 break;
959
36f7ba0a 960 case Bcons:
4015b3c0
GM
961 {
962 Lisp_Object v1;
963 v1 = POP;
964 TOP = Fcons (TOP, v1);
965 break;
966 }
36f7ba0a
JB
967
968 case Blist1:
969 TOP = Fcons (TOP, Qnil);
970 break;
971
972 case Blist2:
4015b3c0
GM
973 {
974 Lisp_Object v1;
975 v1 = POP;
976 TOP = Fcons (TOP, Fcons (v1, Qnil));
977 break;
978 }
36f7ba0a
JB
979
980 case Blist3:
63639d44 981 DISCARD (2);
36f7ba0a
JB
982 TOP = Flist (3, &TOP);
983 break;
984
985 case Blist4:
63639d44 986 DISCARD (3);
36f7ba0a
JB
987 TOP = Flist (4, &TOP);
988 break;
989
63639d44
JB
990 case BlistN:
991 op = FETCH;
992 DISCARD (op - 1);
993 TOP = Flist (op, &TOP);
994 break;
995
36f7ba0a 996 case Blength:
bf1de43e 997 BEFORE_POTENTIAL_GC ();
36f7ba0a 998 TOP = Flength (TOP);
bf1de43e 999 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1000 break;
1001
1002 case Baref:
4015b3c0
GM
1003 {
1004 Lisp_Object v1;
bf1de43e 1005 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1006 v1 = POP;
1007 TOP = Faref (TOP, v1);
bf1de43e 1008 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1009 break;
1010 }
36f7ba0a
JB
1011
1012 case Baset:
4015b3c0
GM
1013 {
1014 Lisp_Object v1, v2;
bf1de43e 1015 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1016 v2 = POP; v1 = POP;
1017 TOP = Faset (TOP, v1, v2);
bf1de43e 1018 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1019 break;
1020 }
36f7ba0a
JB
1021
1022 case Bsymbol_value:
bf1de43e 1023 BEFORE_POTENTIAL_GC ();
36f7ba0a 1024 TOP = Fsymbol_value (TOP);
bf1de43e 1025 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1026 break;
1027
1028 case Bsymbol_function:
bf1de43e 1029 BEFORE_POTENTIAL_GC ();
36f7ba0a 1030 TOP = Fsymbol_function (TOP);
bf1de43e 1031 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1032 break;
1033
1034 case Bset:
4015b3c0
GM
1035 {
1036 Lisp_Object v1;
bf1de43e 1037 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1038 v1 = POP;
1039 TOP = Fset (TOP, v1);
bf1de43e 1040 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1041 break;
1042 }
36f7ba0a
JB
1043
1044 case Bfset:
4015b3c0
GM
1045 {
1046 Lisp_Object v1;
bf1de43e 1047 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1048 v1 = POP;
1049 TOP = Ffset (TOP, v1);
bf1de43e 1050 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1051 break;
1052 }
36f7ba0a
JB
1053
1054 case Bget:
4015b3c0
GM
1055 {
1056 Lisp_Object v1;
bf1de43e 1057 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1058 v1 = POP;
1059 TOP = Fget (TOP, v1);
bf1de43e 1060 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1061 break;
1062 }
36f7ba0a
JB
1063
1064 case Bsubstring:
4015b3c0
GM
1065 {
1066 Lisp_Object v1, v2;
fa9aabf6 1067 BEFORE_POTENTIAL_GC ();
bf1de43e 1068 v2 = POP; v1 = POP;
4015b3c0 1069 TOP = Fsubstring (TOP, v1, v2);
fa9aabf6 1070 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1071 break;
1072 }
36f7ba0a
JB
1073
1074 case Bconcat2:
bf1de43e 1075 BEFORE_POTENTIAL_GC ();
63639d44 1076 DISCARD (1);
36f7ba0a 1077 TOP = Fconcat (2, &TOP);
bf1de43e 1078 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1079 break;
1080
1081 case Bconcat3:
bf1de43e 1082 BEFORE_POTENTIAL_GC ();
63639d44 1083 DISCARD (2);
36f7ba0a 1084 TOP = Fconcat (3, &TOP);
bf1de43e 1085 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1086 break;
1087
1088 case Bconcat4:
bf1de43e 1089 BEFORE_POTENTIAL_GC ();
63639d44 1090 DISCARD (3);
36f7ba0a 1091 TOP = Fconcat (4, &TOP);
bf1de43e 1092 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1093 break;
1094
63639d44
JB
1095 case BconcatN:
1096 op = FETCH;
bf1de43e 1097 BEFORE_POTENTIAL_GC ();
63639d44
JB
1098 DISCARD (op - 1);
1099 TOP = Fconcat (op, &TOP);
bf1de43e 1100 AFTER_POTENTIAL_GC ();
63639d44
JB
1101 break;
1102
36f7ba0a 1103 case Bsub1:
4015b3c0
GM
1104 {
1105 Lisp_Object v1;
1106 v1 = TOP;
1107 if (INTEGERP (v1))
1108 {
1109 XSETINT (v1, XINT (v1) - 1);
1110 TOP = v1;
1111 }
1112 else
e494eee5
MB
1113 {
1114 BEFORE_POTENTIAL_GC ();
1115 TOP = Fsub1 (v1);
1116 AFTER_POTENTIAL_GC ();
1117 }
4015b3c0
GM
1118 break;
1119 }
36f7ba0a
JB
1120
1121 case Badd1:
4015b3c0
GM
1122 {
1123 Lisp_Object v1;
1124 v1 = TOP;
1125 if (INTEGERP (v1))
1126 {
1127 XSETINT (v1, XINT (v1) + 1);
1128 TOP = v1;
1129 }
1130 else
bf1de43e
GM
1131 {
1132 BEFORE_POTENTIAL_GC ();
1133 TOP = Fadd1 (v1);
1134 AFTER_POTENTIAL_GC ();
1135 }
4015b3c0
GM
1136 break;
1137 }
36f7ba0a
JB
1138
1139 case Beqlsign:
4015b3c0
GM
1140 {
1141 Lisp_Object v1, v2;
f5941bf8 1142 BEFORE_POTENTIAL_GC ();
bf1de43e 1143 v2 = POP; v1 = TOP;
b7826503
PJ
1144 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (v1);
1145 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (v2);
f5941bf8 1146 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1147 if (FLOATP (v1) || FLOATP (v2))
1148 {
1149 double f1, f2;
1150
1151 f1 = (FLOATP (v1) ? XFLOAT_DATA (v1) : XINT (v1));
1152 f2 = (FLOATP (v2) ? XFLOAT_DATA (v2) : XINT (v2));
1153 TOP = (f1 == f2 ? Qt : Qnil);
1154 }
1155 else
4015b3c0
GM
1156 TOP = (XINT (v1) == XINT (v2) ? Qt : Qnil);
1157 break;
1158 }
36f7ba0a
JB
1159
1160 case Bgtr:
4015b3c0
GM
1161 {
1162 Lisp_Object v1;
bf1de43e 1163 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1164 v1 = POP;
1165 TOP = Fgtr (TOP, v1);
bf1de43e 1166 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1167 break;
1168 }
36f7ba0a
JB
1169
1170 case Blss:
4015b3c0
GM
1171 {
1172 Lisp_Object v1;
bf1de43e 1173 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1174 v1 = POP;
1175 TOP = Flss (TOP, v1);
bf1de43e 1176 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1177 break;
1178 }
36f7ba0a
JB
1179
1180 case Bleq:
4015b3c0
GM
1181 {
1182 Lisp_Object v1;
bf1de43e 1183 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1184 v1 = POP;
1185 TOP = Fleq (TOP, v1);
bf1de43e 1186 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1187 break;
1188 }
36f7ba0a
JB
1189
1190 case Bgeq:
4015b3c0
GM
1191 {
1192 Lisp_Object v1;
d9c1f6f9 1193 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1194 v1 = POP;
1195 TOP = Fgeq (TOP, v1);
d9c1f6f9 1196 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1197 break;
1198 }
36f7ba0a
JB
1199
1200 case Bdiff:
bf1de43e 1201 BEFORE_POTENTIAL_GC ();
63639d44 1202 DISCARD (1);
36f7ba0a 1203 TOP = Fminus (2, &TOP);
bf1de43e 1204 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1205 break;
1206
1207 case Bnegate:
4015b3c0
GM
1208 {
1209 Lisp_Object v1;
1210 v1 = TOP;
1211 if (INTEGERP (v1))
1212 {
1213 XSETINT (v1, - XINT (v1));
1214 TOP = v1;
1215 }
1216 else
bf1de43e
GM
1217 {
1218 BEFORE_POTENTIAL_GC ();
1219 TOP = Fminus (1, &TOP);
1220 AFTER_POTENTIAL_GC ();
1221 }
4015b3c0
GM
1222 break;
1223 }
36f7ba0a
JB
1224
1225 case Bplus:
bf1de43e 1226 BEFORE_POTENTIAL_GC ();
63639d44 1227 DISCARD (1);
36f7ba0a 1228 TOP = Fplus (2, &TOP);
bf1de43e 1229 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1230 break;
1231
1232 case Bmax:
bf1de43e 1233 BEFORE_POTENTIAL_GC ();
63639d44 1234 DISCARD (1);
36f7ba0a 1235 TOP = Fmax (2, &TOP);
bf1de43e 1236 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1237 break;
1238
1239 case Bmin:
bf1de43e 1240 BEFORE_POTENTIAL_GC ();
63639d44 1241 DISCARD (1);
36f7ba0a 1242 TOP = Fmin (2, &TOP);
bf1de43e 1243 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1244 break;
1245
1246 case Bmult:
bf1de43e 1247 BEFORE_POTENTIAL_GC ();
63639d44 1248 DISCARD (1);
36f7ba0a 1249 TOP = Ftimes (2, &TOP);
bf1de43e 1250 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1251 break;
1252
1253 case Bquo:
bf1de43e 1254 BEFORE_POTENTIAL_GC ();
63639d44 1255 DISCARD (1);
36f7ba0a 1256 TOP = Fquo (2, &TOP);
bf1de43e 1257 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1258 break;
1259
1260 case Brem:
4015b3c0
GM
1261 {
1262 Lisp_Object v1;
bf1de43e 1263 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1264 v1 = POP;
1265 TOP = Frem (TOP, v1);
bf1de43e 1266 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1267 break;
1268 }
36f7ba0a
JB
1269
1270 case Bpoint:
4015b3c0
GM
1271 {
1272 Lisp_Object v1;
1273 XSETFASTINT (v1, PT);
1274 PUSH (v1);
1275 break;
1276 }
36f7ba0a
JB
1277
1278 case Bgoto_char:
4015b3c0 1279 BEFORE_POTENTIAL_GC ();
36f7ba0a 1280 TOP = Fgoto_char (TOP);
4015b3c0 1281 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1282 break;
1283
1284 case Binsert:
4015b3c0 1285 BEFORE_POTENTIAL_GC ();
36f7ba0a 1286 TOP = Finsert (1, &TOP);
4015b3c0 1287 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1288 break;
1289
63639d44
JB
1290 case BinsertN:
1291 op = FETCH;
4015b3c0 1292 BEFORE_POTENTIAL_GC ();
fa9aabf6 1293 DISCARD (op - 1);
63639d44 1294 TOP = Finsert (op, &TOP);
4015b3c0 1295 AFTER_POTENTIAL_GC ();
63639d44
JB
1296 break;
1297
36f7ba0a 1298 case Bpoint_max:
4015b3c0
GM
1299 {
1300 Lisp_Object v1;
1301 XSETFASTINT (v1, ZV);
1302 PUSH (v1);
1303 break;
1304 }
36f7ba0a
JB
1305
1306 case Bpoint_min:
4015b3c0
GM
1307 {
1308 Lisp_Object v1;
1309 XSETFASTINT (v1, BEGV);
1310 PUSH (v1);
1311 break;
1312 }
36f7ba0a
JB
1313
1314 case Bchar_after:
bf1de43e 1315 BEFORE_POTENTIAL_GC ();
36f7ba0a 1316 TOP = Fchar_after (TOP);
bf1de43e 1317 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1318 break;
1319
1320 case Bfollowing_char:
4015b3c0
GM
1321 {
1322 Lisp_Object v1;
bf1de43e 1323 BEFORE_POTENTIAL_GC ();
4015b3c0 1324 v1 = Ffollowing_char ();
bf1de43e 1325 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1326 PUSH (v1);
1327 break;
1328 }
36f7ba0a
JB
1329
1330 case Bpreceding_char:
4015b3c0
GM
1331 {
1332 Lisp_Object v1;
bf1de43e 1333 BEFORE_POTENTIAL_GC ();
4015b3c0 1334 v1 = Fprevious_char ();
bf1de43e 1335 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1336 PUSH (v1);
1337 break;
1338 }
36f7ba0a
JB
1339
1340 case Bcurrent_column:
4015b3c0
GM
1341 {
1342 Lisp_Object v1;
96111f48 1343 BEFORE_POTENTIAL_GC ();
8e11578b 1344 XSETFASTINT (v1, (int) current_column ()); /* iftc */
96111f48 1345 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1346 PUSH (v1);
1347 break;
1348 }
36f7ba0a
JB
1349
1350 case Bindent_to:
4015b3c0 1351 BEFORE_POTENTIAL_GC ();
36f7ba0a 1352 TOP = Findent_to (TOP, Qnil);
4015b3c0 1353 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1354 break;
1355
1356 case Beolp:
1357 PUSH (Feolp ());
1358 break;
1359
1360 case Beobp:
1361 PUSH (Feobp ());
1362 break;
1363
1364 case Bbolp:
1365 PUSH (Fbolp ());
1366 break;
1367
1368 case Bbobp:
1369 PUSH (Fbobp ());
1370 break;
1371
1372 case Bcurrent_buffer:
1373 PUSH (Fcurrent_buffer ());
1374 break;
1375
1376 case Bset_buffer:
4015b3c0 1377 BEFORE_POTENTIAL_GC ();
36f7ba0a 1378 TOP = Fset_buffer (TOP);
4015b3c0 1379 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1380 break;
1381
36f7ba0a
JB
1382 case Binteractive_p:
1383 PUSH (Finteractive_p ());
1384 break;
1385
1386 case Bforward_char:
4015b3c0 1387 BEFORE_POTENTIAL_GC ();
36f7ba0a 1388 TOP = Fforward_char (TOP);
4015b3c0 1389 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1390 break;
1391
1392 case Bforward_word:
4015b3c0 1393 BEFORE_POTENTIAL_GC ();
36f7ba0a 1394 TOP = Fforward_word (TOP);
4015b3c0 1395 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1396 break;
1397
1398 case Bskip_chars_forward:
4015b3c0
GM
1399 {
1400 Lisp_Object v1;
4015b3c0 1401 BEFORE_POTENTIAL_GC ();
bf1de43e 1402 v1 = POP;
4015b3c0
GM
1403 TOP = Fskip_chars_forward (TOP, v1);
1404 AFTER_POTENTIAL_GC ();
1405 break;
1406 }
36f7ba0a
JB
1407
1408 case Bskip_chars_backward:
4015b3c0
GM
1409 {
1410 Lisp_Object v1;
4015b3c0 1411 BEFORE_POTENTIAL_GC ();
bf1de43e 1412 v1 = POP;
4015b3c0
GM
1413 TOP = Fskip_chars_backward (TOP, v1);
1414 AFTER_POTENTIAL_GC ();
1415 break;
1416 }
36f7ba0a
JB
1417
1418 case Bforward_line:
4015b3c0 1419 BEFORE_POTENTIAL_GC ();
36f7ba0a 1420 TOP = Fforward_line (TOP);
4015b3c0 1421 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1422 break;
1423
1424 case Bchar_syntax:
f5941bf8 1425 BEFORE_POTENTIAL_GC ();
b7826503 1426 CHECK_NUMBER (TOP);
f5941bf8 1427 AFTER_POTENTIAL_GC ();
4015b3c0 1428 XSETFASTINT (TOP, syntax_code_spec[(int) SYNTAX (XINT (TOP))]);
36f7ba0a
JB
1429 break;
1430
1431 case Bbuffer_substring:
4015b3c0
GM
1432 {
1433 Lisp_Object v1;
4015b3c0 1434 BEFORE_POTENTIAL_GC ();
bf1de43e 1435 v1 = POP;
4015b3c0
GM
1436 TOP = Fbuffer_substring (TOP, v1);
1437 AFTER_POTENTIAL_GC ();
1438 break;
1439 }
36f7ba0a
JB
1440
1441 case Bdelete_region:
4015b3c0
GM
1442 {
1443 Lisp_Object v1;
4015b3c0 1444 BEFORE_POTENTIAL_GC ();
bf1de43e 1445 v1 = POP;
4015b3c0
GM
1446 TOP = Fdelete_region (TOP, v1);
1447 AFTER_POTENTIAL_GC ();
1448 break;
1449 }
36f7ba0a
JB
1450
1451 case Bnarrow_to_region:
4015b3c0
GM
1452 {
1453 Lisp_Object v1;
4015b3c0 1454 BEFORE_POTENTIAL_GC ();
bf1de43e 1455 v1 = POP;
4015b3c0
GM
1456 TOP = Fnarrow_to_region (TOP, v1);
1457 AFTER_POTENTIAL_GC ();
1458 break;
1459 }
36f7ba0a
JB
1460
1461 case Bwiden:
4015b3c0 1462 BEFORE_POTENTIAL_GC ();
36f7ba0a 1463 PUSH (Fwiden ());
4015b3c0 1464 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1465 break;
1466
63639d44 1467 case Bend_of_line:
4015b3c0 1468 BEFORE_POTENTIAL_GC ();
63639d44 1469 TOP = Fend_of_line (TOP);
4015b3c0 1470 AFTER_POTENTIAL_GC ();
63639d44
JB
1471 break;
1472
1473 case Bset_marker:
4015b3c0
GM
1474 {
1475 Lisp_Object v1, v2;
bf1de43e 1476 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1477 v1 = POP;
1478 v2 = POP;
1479 TOP = Fset_marker (TOP, v2, v1);
bf1de43e 1480 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1481 break;
1482 }
63639d44
JB
1483
1484 case Bmatch_beginning:
bf1de43e 1485 BEFORE_POTENTIAL_GC ();
63639d44 1486 TOP = Fmatch_beginning (TOP);
bf1de43e 1487 AFTER_POTENTIAL_GC ();
63639d44
JB
1488 break;
1489
1490 case Bmatch_end:
bf1de43e 1491 BEFORE_POTENTIAL_GC ();
63639d44 1492 TOP = Fmatch_end (TOP);
bf1de43e 1493 AFTER_POTENTIAL_GC ();
63639d44
JB
1494 break;
1495
1496 case Bupcase:
bf1de43e 1497 BEFORE_POTENTIAL_GC ();
63639d44 1498 TOP = Fupcase (TOP);
bf1de43e 1499 AFTER_POTENTIAL_GC ();
63639d44
JB
1500 break;
1501
1502 case Bdowncase:
bf1de43e 1503 BEFORE_POTENTIAL_GC ();
63639d44 1504 TOP = Fdowncase (TOP);
bf1de43e 1505 AFTER_POTENTIAL_GC ();
63639d44
JB
1506 break;
1507
36f7ba0a 1508 case Bstringeqlsign:
4015b3c0
GM
1509 {
1510 Lisp_Object v1;
bf1de43e 1511 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1512 v1 = POP;
1513 TOP = Fstring_equal (TOP, v1);
bf1de43e 1514 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1515 break;
1516 }
36f7ba0a
JB
1517
1518 case Bstringlss:
4015b3c0
GM
1519 {
1520 Lisp_Object v1;
bf1de43e 1521 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1522 v1 = POP;
1523 TOP = Fstring_lessp (TOP, v1);
bf1de43e 1524 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1525 break;
1526 }
36f7ba0a
JB
1527
1528 case Bequal:
4015b3c0
GM
1529 {
1530 Lisp_Object v1;
1531 v1 = POP;
1532 TOP = Fequal (TOP, v1);
1533 break;
1534 }
36f7ba0a
JB
1535
1536 case Bnthcdr:
4015b3c0
GM
1537 {
1538 Lisp_Object v1;
bf1de43e 1539 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1540 v1 = POP;
1541 TOP = Fnthcdr (TOP, v1);
bf1de43e 1542 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1543 break;
1544 }
36f7ba0a
JB
1545
1546 case Belt:
4015b3c0
GM
1547 {
1548 Lisp_Object v1, v2;
1549 if (CONSP (TOP))
1550 {
1551 /* Exchange args and then do nth. */
bf1de43e 1552 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1553 v2 = POP;
1554 v1 = TOP;
b7826503 1555 CHECK_NUMBER (v2);
f5941bf8 1556 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1557 op = XINT (v2);
1558 immediate_quit = 1;
1559 while (--op >= 0)
1560 {
1561 if (CONSP (v1))
1562 v1 = XCDR (v1);
1563 else if (!NILP (v1))
1564 {
1565 immediate_quit = 0;
892a8eb5 1566 wrong_type_argument (Qlistp, v1);
4015b3c0
GM
1567 }
1568 }
1569 immediate_quit = 0;
fa9aabf6
GM
1570 if (CONSP (v1))
1571 TOP = XCAR (v1);
1572 else if (NILP (v1))
1573 TOP = Qnil;
1574 else
892a8eb5 1575 wrong_type_argument (Qlistp, v1);
4015b3c0
GM
1576 }
1577 else
1578 {
bf1de43e 1579 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1580 v1 = POP;
1581 TOP = Felt (TOP, v1);
bf1de43e 1582 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1583 }
1584 break;
1585 }
36f7ba0a
JB
1586
1587 case Bmember:
4015b3c0
GM
1588 {
1589 Lisp_Object v1;
bf1de43e 1590 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1591 v1 = POP;
1592 TOP = Fmember (TOP, v1);
bf1de43e 1593 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1594 break;
1595 }
36f7ba0a
JB
1596
1597 case Bassq:
4015b3c0
GM
1598 {
1599 Lisp_Object v1;
bf1de43e 1600 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1601 v1 = POP;
1602 TOP = Fassq (TOP, v1);
bf1de43e 1603 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1604 break;
1605 }
36f7ba0a
JB
1606
1607 case Bnreverse:
bf1de43e 1608 BEFORE_POTENTIAL_GC ();
36f7ba0a 1609 TOP = Fnreverse (TOP);
bf1de43e 1610 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1611 break;
1612
1613 case Bsetcar:
4015b3c0
GM
1614 {
1615 Lisp_Object v1;
bf1de43e 1616 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1617 v1 = POP;
1618 TOP = Fsetcar (TOP, v1);
bf1de43e 1619 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1620 break;
1621 }
36f7ba0a
JB
1622
1623 case Bsetcdr:
4015b3c0
GM
1624 {
1625 Lisp_Object v1;
bf1de43e 1626 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1627 v1 = POP;
1628 TOP = Fsetcdr (TOP, v1);
bf1de43e 1629 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1630 break;
1631 }
36f7ba0a
JB
1632
1633 case Bcar_safe:
4015b3c0
GM
1634 {
1635 Lisp_Object v1;
1636 v1 = TOP;
1637 if (CONSP (v1))
1638 TOP = XCAR (v1);
1639 else
1640 TOP = Qnil;
1641 break;
1642 }
36f7ba0a
JB
1643
1644 case Bcdr_safe:
4015b3c0
GM
1645 {
1646 Lisp_Object v1;
1647 v1 = TOP;
1648 if (CONSP (v1))
1649 TOP = XCDR (v1);
1650 else
1651 TOP = Qnil;
1652 break;
1653 }
36f7ba0a
JB
1654
1655 case Bnconc:
bf1de43e 1656 BEFORE_POTENTIAL_GC ();
63639d44 1657 DISCARD (1);
36f7ba0a 1658 TOP = Fnconc (2, &TOP);
bf1de43e 1659 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1660 break;
1661
1662 case Bnumberp:
63639d44 1663 TOP = (NUMBERP (TOP) ? Qt : Qnil);
36f7ba0a
JB
1664 break;
1665
1666 case Bintegerp:
617bd3f6 1667 TOP = INTEGERP (TOP) ? Qt : Qnil;
36f7ba0a
JB
1668 break;
1669
1670#ifdef BYTE_CODE_SAFE
1671 case Bset_mark:
f5941bf8 1672 BEFORE_POTENTIAL_GC ();
36f7ba0a 1673 error ("set-mark is an obsolete bytecode");
f5941bf8 1674 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1675 break;
1676 case Bscan_buffer:
f5941bf8 1677 BEFORE_POTENTIAL_GC ();
36f7ba0a 1678 error ("scan-buffer is an obsolete bytecode");
f5941bf8 1679 AFTER_POTENTIAL_GC ();
36f7ba0a 1680 break;
36f7ba0a
JB
1681#endif
1682
c96d71f7
RS
1683 case 0:
1684 abort ();
1685
1686 case 255:
36f7ba0a
JB
1687 default:
1688#ifdef BYTE_CODE_SAFE
1689 if (op < Bconstant)
f5941bf8 1690 {
cc94f3b2 1691 abort ();
f5941bf8 1692 }
36f7ba0a 1693 if ((op -= Bconstant) >= const_length)
f5941bf8 1694 {
cc94f3b2 1695 abort ();
f5941bf8 1696 }
36f7ba0a
JB
1697 PUSH (vectorp[op]);
1698#else
1699 PUSH (vectorp[op - Bconstant]);
1700#endif
1701 }
1702 }
1703
1704 exit:
7ca1e8b7
GM
1705
1706 byte_stack_list = byte_stack_list->next;
1707
36f7ba0a 1708 /* Binds and unbinds are supposed to be compiled balanced. */
aed13378 1709 if (SPECPDL_INDEX () != count)
36f7ba0a
JB
1710#ifdef BYTE_CODE_SAFE
1711 error ("binding stack not balanced (serious byte compiler bug)");
1712#else
1713 abort ();
1714#endif
8e11578b 1715
4015b3c0 1716 return result;
36f7ba0a
JB
1717}
1718
dfcf069d 1719void
36f7ba0a
JB
1720syms_of_bytecode ()
1721{
1722 Qbytecode = intern ("byte-code");
1723 staticpro (&Qbytecode);
1724
1725 defsubr (&Sbyte_code);
1726
1727#ifdef BYTE_CODE_METER
1728
1729 DEFVAR_LISP ("byte-code-meter", &Vbyte_code_meter,
39f624fa
PJ
1730 doc: /* A vector of vectors which holds a histogram of byte-code usage.
1731\(aref (aref byte-code-meter 0) CODE) indicates how many times the byte
1732opcode CODE has been executed.
1733\(aref (aref byte-code-meter CODE1) CODE2), where CODE1 is not 0,
1734indicates how many times the byte opcodes CODE1 and CODE2 have been
1735executed in succession. */);
8e11578b 1736
63639d44 1737 DEFVAR_BOOL ("byte-metering-on", &byte_metering_on,
39f624fa
PJ
1738 doc: /* If non-nil, keep profiling information on byte code usage.
1739The variable byte-code-meter indicates how often each byte opcode is used.
1740If a symbol has a property named `byte-code-meter' whose value is an
1741integer, it is incremented each time that symbol's function is called. */);
36f7ba0a
JB
1742
1743 byte_metering_on = 0;
63639d44
JB
1744 Vbyte_code_meter = Fmake_vector (make_number (256), make_number (0));
1745 Qbyte_code_meter = intern ("byte-code-meter");
1746 staticpro (&Qbyte_code_meter);
36f7ba0a
JB
1747 {
1748 int i = 256;
1749 while (i--)
63639d44
JB
1750 XVECTOR (Vbyte_code_meter)->contents[i] =
1751 Fmake_vector (make_number (256), make_number (0));
36f7ba0a
JB
1752 }
1753#endif
1754}
ab5796a9
MB
1755
1756/* arch-tag: b9803b6f-1ed6-4190-8adf-33fd3a9d10e9
1757 (do not change this comment) */