Update FSF's address.
[bpt/emacs.git] / src / bytecode.c
CommitLineData
36f7ba0a 1/* Execution of byte code produced by bytecomp.el.
892a8eb5 2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 2000, 2001, 2002, 2003, 2004
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
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
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 { \
731475e7 387 Lisp_Object flag = Vquit_flag; \
e12ea64e
GM
388 Vquit_flag = Qnil; \
389 BEFORE_POTENTIAL_GC (); \
731475e7
KS
390 if (EQ (Vthrow_on_input, flag)) \
391 Fthrow (Vthrow_on_input, Qnil); \
e12ea64e 392 Fsignal (Qquit, Qnil); \
892a8eb5 393 AFTER_POTENTIAL_GC (); \
e12ea64e
GM
394 } \
395 } while (0)
396
7ca1e8b7 397
36f7ba0a 398DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0,
39f624fa
PJ
399 doc: /* Function used internally in byte-compiled code.
400The first argument, BYTESTR, is a string of byte code;
401the second, VECTOR, a vector of constants;
402the third, MAXDEPTH, the maximum stack depth used in this function.
403If the third argument is incorrect, Emacs may crash. */)
404 (bytestr, vector, maxdepth)
36f7ba0a
JB
405 Lisp_Object bytestr, vector, maxdepth;
406{
aed13378 407 int count = SPECPDL_INDEX ();
36f7ba0a
JB
408#ifdef BYTE_CODE_METER
409 int this_op = 0;
410 int prev_op;
411#endif
7ca1e8b7 412 int op;
4015b3c0 413 /* Lisp_Object v1, v2; */
089b985f 414 Lisp_Object *vectorp;
36f7ba0a 415#ifdef BYTE_CODE_SAFE
7ca1e8b7
GM
416 int const_length = XVECTOR (vector)->size;
417 Lisp_Object *stacke;
36f7ba0a 418#endif
089b985f 419 int bytestr_length;
7ca1e8b7
GM
420 struct byte_stack stack;
421 Lisp_Object *top;
4015b3c0 422 Lisp_Object result;
36f7ba0a 423
ad7de7d7
GM
424#ifdef CHECK_FRAME_FONT
425 {
426 struct frame *f = SELECTED_FRAME ();
427 if (FRAME_X_P (f)
428 && FRAME_FONT (f)->direction != 0
429 && FRAME_FONT (f)->direction != 1)
430 abort ();
431 }
432#endif
433
b7826503 434 CHECK_STRING (bytestr);
617bd3f6 435 if (!VECTORP (vector))
36f7ba0a 436 vector = wrong_type_argument (Qvectorp, vector);
b7826503 437 CHECK_NUMBER (maxdepth);
36f7ba0a 438
089b985f
KH
439 if (STRING_MULTIBYTE (bytestr))
440 /* BYTESTR must have been produced by Emacs 20.2 or the earlier
441 because they produced a raw 8-bit string for byte-code and now
442 such a byte-code string is loaded as multibyte while raw 8-bit
443 characters converted to multibyte form. Thus, now we must
fbd98f82 444 convert them back to the originally intended unibyte form. */
5274126b 445 bytestr = Fstring_as_unibyte (bytestr);
089b985f 446
d5db4077 447 bytestr_length = SBYTES (bytestr);
089b985f
KH
448 vectorp = XVECTOR (vector)->contents;
449
7ca1e8b7 450 stack.byte_string = bytestr;
d5db4077 451 stack.pc = stack.byte_string_start = SDATA (bytestr);
7ca1e8b7 452 stack.constants = vector;
8e11578b 453 stack.bottom = (Lisp_Object *) alloca (XFASTINT (maxdepth)
7ca1e8b7
GM
454 * sizeof (Lisp_Object));
455 top = stack.bottom - 1;
456 stack.top = NULL;
457 stack.next = byte_stack_list;
458 byte_stack_list = &stack;
36f7ba0a 459
7ca1e8b7
GM
460#ifdef BYTE_CODE_SAFE
461 stacke = stack.bottom - 1 + XFASTINT (maxdepth);
462#endif
8e11578b 463
36f7ba0a
JB
464 while (1)
465 {
466#ifdef BYTE_CODE_SAFE
9e49c990 467 if (top > stacke)
cc94f3b2 468 abort ();
7ca1e8b7 469 else if (top < stack.bottom - 1)
cc94f3b2 470 abort ();
36f7ba0a
JB
471#endif
472
36f7ba0a
JB
473#ifdef BYTE_CODE_METER
474 prev_op = this_op;
475 this_op = op = FETCH;
476 METER_CODE (prev_op, op);
36f7ba0a 477#else
4015b3c0 478 op = FETCH;
36f7ba0a 479#endif
36f7ba0a 480
4015b3c0
GM
481 switch (op)
482 {
483 case Bvarref + 7:
36f7ba0a
JB
484 op = FETCH2;
485 goto varref;
486
8e11578b
TTN
487 case Bvarref:
488 case Bvarref + 1:
489 case Bvarref + 2:
4015b3c0 490 case Bvarref + 3:
8e11578b 491 case Bvarref + 4:
4015b3c0 492 case Bvarref + 5:
36f7ba0a 493 op = op - Bvarref;
4015b3c0
GM
494 goto varref;
495
496 /* This seems to be the most frequently executed byte-code
497 among the Bvarref's, so avoid a goto here. */
498 case Bvarref+6:
499 op = FETCH;
36f7ba0a 500 varref:
4015b3c0
GM
501 {
502 Lisp_Object v1, v2;
503
504 v1 = vectorp[op];
505 if (SYMBOLP (v1))
506 {
5133a578 507 v2 = SYMBOL_VALUE (v1);
4015b3c0 508 if (MISCP (v2) || EQ (v2, Qunbound))
bf1de43e
GM
509 {
510 BEFORE_POTENTIAL_GC ();
511 v2 = Fsymbol_value (v1);
512 AFTER_POTENTIAL_GC ();
513 }
4015b3c0
GM
514 }
515 else
bf1de43e
GM
516 {
517 BEFORE_POTENTIAL_GC ();
518 v2 = Fsymbol_value (v1);
519 AFTER_POTENTIAL_GC ();
520 }
4015b3c0
GM
521 PUSH (v2);
522 break;
523 }
524
525 case Bgotoifnil:
526 MAYBE_GC ();
527 op = FETCH2;
528 if (NILP (POP))
36f7ba0a 529 {
e12ea64e 530 BYTE_CODE_QUIT;
4015b3c0
GM
531 CHECK_RANGE (op);
532 stack.pc = stack.byte_string_start + op;
36f7ba0a 533 }
36f7ba0a
JB
534 break;
535
4015b3c0
GM
536 case Bcar:
537 {
538 Lisp_Object v1;
539 v1 = TOP;
fa9aabf6
GM
540 if (CONSP (v1))
541 TOP = XCAR (v1);
542 else if (NILP (v1))
543 TOP = Qnil;
544 else
f5941bf8 545 {
892a8eb5 546 wrong_type_argument (Qlistp, v1);
f5941bf8 547 }
4015b3c0
GM
548 break;
549 }
550
551 case Beq:
552 {
553 Lisp_Object v1;
554 v1 = POP;
555 TOP = EQ (v1, TOP) ? Qt : Qnil;
556 break;
557 }
558
559 case Bmemq:
560 {
561 Lisp_Object v1;
bf1de43e 562 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
563 v1 = POP;
564 TOP = Fmemq (TOP, v1);
bf1de43e 565 AFTER_POTENTIAL_GC ();
4015b3c0
GM
566 break;
567 }
568
569 case Bcdr:
570 {
571 Lisp_Object v1;
572 v1 = TOP;
fa9aabf6
GM
573 if (CONSP (v1))
574 TOP = XCDR (v1);
575 else if (NILP (v1))
576 TOP = Qnil;
577 else
f5941bf8 578 {
892a8eb5 579 wrong_type_argument (Qlistp, v1);
f5941bf8 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:
ba3fb063 858 record_unwind_protect (Fprogn, POP);
36f7ba0a
JB
859 break;
860
861 case Bcondition_case:
4015b3c0
GM
862 {
863 Lisp_Object v1;
864 v1 = POP;
865 v1 = Fcons (POP, v1);
866 BEFORE_POTENTIAL_GC ();
867 TOP = Fcondition_case (Fcons (TOP, v1));
868 AFTER_POTENTIAL_GC ();
869 break;
870 }
36f7ba0a
JB
871
872 case Btemp_output_buffer_setup:
4015b3c0 873 BEFORE_POTENTIAL_GC ();
b7826503 874 CHECK_STRING (TOP);
d5db4077 875 temp_output_buffer_setup (SDATA (TOP));
4015b3c0 876 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
877 TOP = Vstandard_output;
878 break;
879
880 case Btemp_output_buffer_show:
4015b3c0
GM
881 {
882 Lisp_Object v1;
4015b3c0 883 BEFORE_POTENTIAL_GC ();
bf1de43e 884 v1 = POP;
4015b3c0
GM
885 temp_output_buffer_show (TOP);
886 TOP = v1;
887 /* pop binding of standard-output */
aed13378 888 unbind_to (SPECPDL_INDEX () - 1, Qnil);
4015b3c0
GM
889 AFTER_POTENTIAL_GC ();
890 break;
891 }
36f7ba0a
JB
892
893 case Bnth:
4015b3c0
GM
894 {
895 Lisp_Object v1, v2;
bf1de43e 896 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
897 v1 = POP;
898 v2 = TOP;
b7826503 899 CHECK_NUMBER (v2);
f5941bf8 900 AFTER_POTENTIAL_GC ();
4015b3c0
GM
901 op = XINT (v2);
902 immediate_quit = 1;
903 while (--op >= 0)
904 {
905 if (CONSP (v1))
906 v1 = XCDR (v1);
907 else if (!NILP (v1))
908 {
909 immediate_quit = 0;
892a8eb5 910 wrong_type_argument (Qlistp, v1);
4015b3c0
GM
911 }
912 }
913 immediate_quit = 0;
fa9aabf6
GM
914 if (CONSP (v1))
915 TOP = XCAR (v1);
916 else if (NILP (v1))
917 TOP = Qnil;
918 else
892a8eb5 919 wrong_type_argument (Qlistp, v1);
4015b3c0
GM
920 break;
921 }
36f7ba0a
JB
922
923 case Bsymbolp:
617bd3f6 924 TOP = SYMBOLP (TOP) ? Qt : Qnil;
36f7ba0a
JB
925 break;
926
927 case Bconsp:
928 TOP = CONSP (TOP) ? Qt : Qnil;
929 break;
930
931 case Bstringp:
617bd3f6 932 TOP = STRINGP (TOP) ? Qt : Qnil;
36f7ba0a
JB
933 break;
934
935 case Blistp:
921a8935 936 TOP = CONSP (TOP) || NILP (TOP) ? Qt : Qnil;
36f7ba0a
JB
937 break;
938
36f7ba0a 939 case Bnot:
921a8935 940 TOP = NILP (TOP) ? Qt : Qnil;
36f7ba0a
JB
941 break;
942
36f7ba0a 943 case Bcons:
4015b3c0
GM
944 {
945 Lisp_Object v1;
946 v1 = POP;
947 TOP = Fcons (TOP, v1);
948 break;
949 }
36f7ba0a
JB
950
951 case Blist1:
952 TOP = Fcons (TOP, Qnil);
953 break;
954
955 case Blist2:
4015b3c0
GM
956 {
957 Lisp_Object v1;
958 v1 = POP;
959 TOP = Fcons (TOP, Fcons (v1, Qnil));
960 break;
961 }
36f7ba0a
JB
962
963 case Blist3:
63639d44 964 DISCARD (2);
36f7ba0a
JB
965 TOP = Flist (3, &TOP);
966 break;
967
968 case Blist4:
63639d44 969 DISCARD (3);
36f7ba0a
JB
970 TOP = Flist (4, &TOP);
971 break;
972
63639d44
JB
973 case BlistN:
974 op = FETCH;
975 DISCARD (op - 1);
976 TOP = Flist (op, &TOP);
977 break;
978
36f7ba0a 979 case Blength:
bf1de43e 980 BEFORE_POTENTIAL_GC ();
36f7ba0a 981 TOP = Flength (TOP);
bf1de43e 982 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
983 break;
984
985 case Baref:
4015b3c0
GM
986 {
987 Lisp_Object v1;
bf1de43e 988 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
989 v1 = POP;
990 TOP = Faref (TOP, v1);
bf1de43e 991 AFTER_POTENTIAL_GC ();
4015b3c0
GM
992 break;
993 }
36f7ba0a
JB
994
995 case Baset:
4015b3c0
GM
996 {
997 Lisp_Object v1, v2;
bf1de43e 998 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
999 v2 = POP; v1 = POP;
1000 TOP = Faset (TOP, v1, v2);
bf1de43e 1001 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1002 break;
1003 }
36f7ba0a
JB
1004
1005 case Bsymbol_value:
bf1de43e 1006 BEFORE_POTENTIAL_GC ();
36f7ba0a 1007 TOP = Fsymbol_value (TOP);
bf1de43e 1008 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1009 break;
1010
1011 case Bsymbol_function:
bf1de43e 1012 BEFORE_POTENTIAL_GC ();
36f7ba0a 1013 TOP = Fsymbol_function (TOP);
bf1de43e 1014 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1015 break;
1016
1017 case Bset:
4015b3c0
GM
1018 {
1019 Lisp_Object v1;
bf1de43e 1020 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1021 v1 = POP;
1022 TOP = Fset (TOP, v1);
bf1de43e 1023 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1024 break;
1025 }
36f7ba0a
JB
1026
1027 case Bfset:
4015b3c0
GM
1028 {
1029 Lisp_Object v1;
bf1de43e 1030 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1031 v1 = POP;
1032 TOP = Ffset (TOP, v1);
bf1de43e 1033 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1034 break;
1035 }
36f7ba0a
JB
1036
1037 case Bget:
4015b3c0
GM
1038 {
1039 Lisp_Object v1;
bf1de43e 1040 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1041 v1 = POP;
1042 TOP = Fget (TOP, v1);
bf1de43e 1043 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1044 break;
1045 }
36f7ba0a
JB
1046
1047 case Bsubstring:
4015b3c0
GM
1048 {
1049 Lisp_Object v1, v2;
fa9aabf6 1050 BEFORE_POTENTIAL_GC ();
bf1de43e 1051 v2 = POP; v1 = POP;
4015b3c0 1052 TOP = Fsubstring (TOP, v1, v2);
fa9aabf6 1053 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1054 break;
1055 }
36f7ba0a
JB
1056
1057 case Bconcat2:
bf1de43e 1058 BEFORE_POTENTIAL_GC ();
63639d44 1059 DISCARD (1);
36f7ba0a 1060 TOP = Fconcat (2, &TOP);
bf1de43e 1061 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1062 break;
1063
1064 case Bconcat3:
bf1de43e 1065 BEFORE_POTENTIAL_GC ();
63639d44 1066 DISCARD (2);
36f7ba0a 1067 TOP = Fconcat (3, &TOP);
bf1de43e 1068 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1069 break;
1070
1071 case Bconcat4:
bf1de43e 1072 BEFORE_POTENTIAL_GC ();
63639d44 1073 DISCARD (3);
36f7ba0a 1074 TOP = Fconcat (4, &TOP);
bf1de43e 1075 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1076 break;
1077
63639d44
JB
1078 case BconcatN:
1079 op = FETCH;
bf1de43e 1080 BEFORE_POTENTIAL_GC ();
63639d44
JB
1081 DISCARD (op - 1);
1082 TOP = Fconcat (op, &TOP);
bf1de43e 1083 AFTER_POTENTIAL_GC ();
63639d44
JB
1084 break;
1085
36f7ba0a 1086 case Bsub1:
4015b3c0
GM
1087 {
1088 Lisp_Object v1;
1089 v1 = TOP;
1090 if (INTEGERP (v1))
1091 {
1092 XSETINT (v1, XINT (v1) - 1);
1093 TOP = v1;
1094 }
1095 else
e494eee5
MB
1096 {
1097 BEFORE_POTENTIAL_GC ();
1098 TOP = Fsub1 (v1);
1099 AFTER_POTENTIAL_GC ();
1100 }
4015b3c0
GM
1101 break;
1102 }
36f7ba0a
JB
1103
1104 case Badd1:
4015b3c0
GM
1105 {
1106 Lisp_Object v1;
1107 v1 = TOP;
1108 if (INTEGERP (v1))
1109 {
1110 XSETINT (v1, XINT (v1) + 1);
1111 TOP = v1;
1112 }
1113 else
bf1de43e
GM
1114 {
1115 BEFORE_POTENTIAL_GC ();
1116 TOP = Fadd1 (v1);
1117 AFTER_POTENTIAL_GC ();
1118 }
4015b3c0
GM
1119 break;
1120 }
36f7ba0a
JB
1121
1122 case Beqlsign:
4015b3c0
GM
1123 {
1124 Lisp_Object v1, v2;
f5941bf8 1125 BEFORE_POTENTIAL_GC ();
bf1de43e 1126 v2 = POP; v1 = TOP;
b7826503
PJ
1127 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (v1);
1128 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (v2);
f5941bf8 1129 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1130 if (FLOATP (v1) || FLOATP (v2))
1131 {
1132 double f1, f2;
1133
1134 f1 = (FLOATP (v1) ? XFLOAT_DATA (v1) : XINT (v1));
1135 f2 = (FLOATP (v2) ? XFLOAT_DATA (v2) : XINT (v2));
1136 TOP = (f1 == f2 ? Qt : Qnil);
1137 }
1138 else
4015b3c0
GM
1139 TOP = (XINT (v1) == XINT (v2) ? Qt : Qnil);
1140 break;
1141 }
36f7ba0a
JB
1142
1143 case Bgtr:
4015b3c0
GM
1144 {
1145 Lisp_Object v1;
bf1de43e 1146 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1147 v1 = POP;
1148 TOP = Fgtr (TOP, v1);
bf1de43e 1149 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1150 break;
1151 }
36f7ba0a
JB
1152
1153 case Blss:
4015b3c0
GM
1154 {
1155 Lisp_Object v1;
bf1de43e 1156 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1157 v1 = POP;
1158 TOP = Flss (TOP, v1);
bf1de43e 1159 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1160 break;
1161 }
36f7ba0a
JB
1162
1163 case Bleq:
4015b3c0
GM
1164 {
1165 Lisp_Object v1;
bf1de43e 1166 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1167 v1 = POP;
1168 TOP = Fleq (TOP, v1);
bf1de43e 1169 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1170 break;
1171 }
36f7ba0a
JB
1172
1173 case Bgeq:
4015b3c0
GM
1174 {
1175 Lisp_Object v1;
d9c1f6f9 1176 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1177 v1 = POP;
1178 TOP = Fgeq (TOP, v1);
d9c1f6f9 1179 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1180 break;
1181 }
36f7ba0a
JB
1182
1183 case Bdiff:
bf1de43e 1184 BEFORE_POTENTIAL_GC ();
63639d44 1185 DISCARD (1);
36f7ba0a 1186 TOP = Fminus (2, &TOP);
bf1de43e 1187 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1188 break;
1189
1190 case Bnegate:
4015b3c0
GM
1191 {
1192 Lisp_Object v1;
1193 v1 = TOP;
1194 if (INTEGERP (v1))
1195 {
1196 XSETINT (v1, - XINT (v1));
1197 TOP = v1;
1198 }
1199 else
bf1de43e
GM
1200 {
1201 BEFORE_POTENTIAL_GC ();
1202 TOP = Fminus (1, &TOP);
1203 AFTER_POTENTIAL_GC ();
1204 }
4015b3c0
GM
1205 break;
1206 }
36f7ba0a
JB
1207
1208 case Bplus:
bf1de43e 1209 BEFORE_POTENTIAL_GC ();
63639d44 1210 DISCARD (1);
36f7ba0a 1211 TOP = Fplus (2, &TOP);
bf1de43e 1212 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1213 break;
1214
1215 case Bmax:
bf1de43e 1216 BEFORE_POTENTIAL_GC ();
63639d44 1217 DISCARD (1);
36f7ba0a 1218 TOP = Fmax (2, &TOP);
bf1de43e 1219 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1220 break;
1221
1222 case Bmin:
bf1de43e 1223 BEFORE_POTENTIAL_GC ();
63639d44 1224 DISCARD (1);
36f7ba0a 1225 TOP = Fmin (2, &TOP);
bf1de43e 1226 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1227 break;
1228
1229 case Bmult:
bf1de43e 1230 BEFORE_POTENTIAL_GC ();
63639d44 1231 DISCARD (1);
36f7ba0a 1232 TOP = Ftimes (2, &TOP);
bf1de43e 1233 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1234 break;
1235
1236 case Bquo:
bf1de43e 1237 BEFORE_POTENTIAL_GC ();
63639d44 1238 DISCARD (1);
36f7ba0a 1239 TOP = Fquo (2, &TOP);
bf1de43e 1240 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1241 break;
1242
1243 case Brem:
4015b3c0
GM
1244 {
1245 Lisp_Object v1;
bf1de43e 1246 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1247 v1 = POP;
1248 TOP = Frem (TOP, v1);
bf1de43e 1249 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1250 break;
1251 }
36f7ba0a
JB
1252
1253 case Bpoint:
4015b3c0
GM
1254 {
1255 Lisp_Object v1;
1256 XSETFASTINT (v1, PT);
1257 PUSH (v1);
1258 break;
1259 }
36f7ba0a
JB
1260
1261 case Bgoto_char:
4015b3c0 1262 BEFORE_POTENTIAL_GC ();
36f7ba0a 1263 TOP = Fgoto_char (TOP);
4015b3c0 1264 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1265 break;
1266
1267 case Binsert:
4015b3c0 1268 BEFORE_POTENTIAL_GC ();
36f7ba0a 1269 TOP = Finsert (1, &TOP);
4015b3c0 1270 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1271 break;
1272
63639d44
JB
1273 case BinsertN:
1274 op = FETCH;
4015b3c0 1275 BEFORE_POTENTIAL_GC ();
fa9aabf6 1276 DISCARD (op - 1);
63639d44 1277 TOP = Finsert (op, &TOP);
4015b3c0 1278 AFTER_POTENTIAL_GC ();
63639d44
JB
1279 break;
1280
36f7ba0a 1281 case Bpoint_max:
4015b3c0
GM
1282 {
1283 Lisp_Object v1;
1284 XSETFASTINT (v1, ZV);
1285 PUSH (v1);
1286 break;
1287 }
36f7ba0a
JB
1288
1289 case Bpoint_min:
4015b3c0
GM
1290 {
1291 Lisp_Object v1;
1292 XSETFASTINT (v1, BEGV);
1293 PUSH (v1);
1294 break;
1295 }
36f7ba0a
JB
1296
1297 case Bchar_after:
bf1de43e 1298 BEFORE_POTENTIAL_GC ();
36f7ba0a 1299 TOP = Fchar_after (TOP);
bf1de43e 1300 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1301 break;
1302
1303 case Bfollowing_char:
4015b3c0
GM
1304 {
1305 Lisp_Object v1;
bf1de43e 1306 BEFORE_POTENTIAL_GC ();
4015b3c0 1307 v1 = Ffollowing_char ();
bf1de43e 1308 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1309 PUSH (v1);
1310 break;
1311 }
36f7ba0a
JB
1312
1313 case Bpreceding_char:
4015b3c0
GM
1314 {
1315 Lisp_Object v1;
bf1de43e 1316 BEFORE_POTENTIAL_GC ();
4015b3c0 1317 v1 = Fprevious_char ();
bf1de43e 1318 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1319 PUSH (v1);
1320 break;
1321 }
36f7ba0a
JB
1322
1323 case Bcurrent_column:
4015b3c0
GM
1324 {
1325 Lisp_Object v1;
96111f48 1326 BEFORE_POTENTIAL_GC ();
8e11578b 1327 XSETFASTINT (v1, (int) current_column ()); /* iftc */
96111f48 1328 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1329 PUSH (v1);
1330 break;
1331 }
36f7ba0a
JB
1332
1333 case Bindent_to:
4015b3c0 1334 BEFORE_POTENTIAL_GC ();
36f7ba0a 1335 TOP = Findent_to (TOP, Qnil);
4015b3c0 1336 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1337 break;
1338
1339 case Beolp:
1340 PUSH (Feolp ());
1341 break;
1342
1343 case Beobp:
1344 PUSH (Feobp ());
1345 break;
1346
1347 case Bbolp:
1348 PUSH (Fbolp ());
1349 break;
1350
1351 case Bbobp:
1352 PUSH (Fbobp ());
1353 break;
1354
1355 case Bcurrent_buffer:
1356 PUSH (Fcurrent_buffer ());
1357 break;
1358
1359 case Bset_buffer:
4015b3c0 1360 BEFORE_POTENTIAL_GC ();
36f7ba0a 1361 TOP = Fset_buffer (TOP);
4015b3c0 1362 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1363 break;
1364
36f7ba0a
JB
1365 case Binteractive_p:
1366 PUSH (Finteractive_p ());
1367 break;
1368
1369 case Bforward_char:
4015b3c0 1370 BEFORE_POTENTIAL_GC ();
36f7ba0a 1371 TOP = Fforward_char (TOP);
4015b3c0 1372 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1373 break;
1374
1375 case Bforward_word:
4015b3c0 1376 BEFORE_POTENTIAL_GC ();
36f7ba0a 1377 TOP = Fforward_word (TOP);
4015b3c0 1378 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1379 break;
1380
1381 case Bskip_chars_forward:
4015b3c0
GM
1382 {
1383 Lisp_Object v1;
4015b3c0 1384 BEFORE_POTENTIAL_GC ();
bf1de43e 1385 v1 = POP;
4015b3c0
GM
1386 TOP = Fskip_chars_forward (TOP, v1);
1387 AFTER_POTENTIAL_GC ();
1388 break;
1389 }
36f7ba0a
JB
1390
1391 case Bskip_chars_backward:
4015b3c0
GM
1392 {
1393 Lisp_Object v1;
4015b3c0 1394 BEFORE_POTENTIAL_GC ();
bf1de43e 1395 v1 = POP;
4015b3c0
GM
1396 TOP = Fskip_chars_backward (TOP, v1);
1397 AFTER_POTENTIAL_GC ();
1398 break;
1399 }
36f7ba0a
JB
1400
1401 case Bforward_line:
4015b3c0 1402 BEFORE_POTENTIAL_GC ();
36f7ba0a 1403 TOP = Fforward_line (TOP);
4015b3c0 1404 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1405 break;
1406
1407 case Bchar_syntax:
f5941bf8 1408 BEFORE_POTENTIAL_GC ();
b7826503 1409 CHECK_NUMBER (TOP);
f5941bf8 1410 AFTER_POTENTIAL_GC ();
4015b3c0 1411 XSETFASTINT (TOP, syntax_code_spec[(int) SYNTAX (XINT (TOP))]);
36f7ba0a
JB
1412 break;
1413
1414 case Bbuffer_substring:
4015b3c0
GM
1415 {
1416 Lisp_Object v1;
4015b3c0 1417 BEFORE_POTENTIAL_GC ();
bf1de43e 1418 v1 = POP;
4015b3c0
GM
1419 TOP = Fbuffer_substring (TOP, v1);
1420 AFTER_POTENTIAL_GC ();
1421 break;
1422 }
36f7ba0a
JB
1423
1424 case Bdelete_region:
4015b3c0
GM
1425 {
1426 Lisp_Object v1;
4015b3c0 1427 BEFORE_POTENTIAL_GC ();
bf1de43e 1428 v1 = POP;
4015b3c0
GM
1429 TOP = Fdelete_region (TOP, v1);
1430 AFTER_POTENTIAL_GC ();
1431 break;
1432 }
36f7ba0a
JB
1433
1434 case Bnarrow_to_region:
4015b3c0
GM
1435 {
1436 Lisp_Object v1;
4015b3c0 1437 BEFORE_POTENTIAL_GC ();
bf1de43e 1438 v1 = POP;
4015b3c0
GM
1439 TOP = Fnarrow_to_region (TOP, v1);
1440 AFTER_POTENTIAL_GC ();
1441 break;
1442 }
36f7ba0a
JB
1443
1444 case Bwiden:
4015b3c0 1445 BEFORE_POTENTIAL_GC ();
36f7ba0a 1446 PUSH (Fwiden ());
4015b3c0 1447 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1448 break;
1449
63639d44 1450 case Bend_of_line:
4015b3c0 1451 BEFORE_POTENTIAL_GC ();
63639d44 1452 TOP = Fend_of_line (TOP);
4015b3c0 1453 AFTER_POTENTIAL_GC ();
63639d44
JB
1454 break;
1455
1456 case Bset_marker:
4015b3c0
GM
1457 {
1458 Lisp_Object v1, v2;
bf1de43e 1459 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1460 v1 = POP;
1461 v2 = POP;
1462 TOP = Fset_marker (TOP, v2, v1);
bf1de43e 1463 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1464 break;
1465 }
63639d44
JB
1466
1467 case Bmatch_beginning:
bf1de43e 1468 BEFORE_POTENTIAL_GC ();
63639d44 1469 TOP = Fmatch_beginning (TOP);
bf1de43e 1470 AFTER_POTENTIAL_GC ();
63639d44
JB
1471 break;
1472
1473 case Bmatch_end:
bf1de43e 1474 BEFORE_POTENTIAL_GC ();
63639d44 1475 TOP = Fmatch_end (TOP);
bf1de43e 1476 AFTER_POTENTIAL_GC ();
63639d44
JB
1477 break;
1478
1479 case Bupcase:
bf1de43e 1480 BEFORE_POTENTIAL_GC ();
63639d44 1481 TOP = Fupcase (TOP);
bf1de43e 1482 AFTER_POTENTIAL_GC ();
63639d44
JB
1483 break;
1484
1485 case Bdowncase:
bf1de43e 1486 BEFORE_POTENTIAL_GC ();
63639d44 1487 TOP = Fdowncase (TOP);
bf1de43e 1488 AFTER_POTENTIAL_GC ();
63639d44
JB
1489 break;
1490
36f7ba0a 1491 case Bstringeqlsign:
4015b3c0
GM
1492 {
1493 Lisp_Object v1;
bf1de43e 1494 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1495 v1 = POP;
1496 TOP = Fstring_equal (TOP, v1);
bf1de43e 1497 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1498 break;
1499 }
36f7ba0a
JB
1500
1501 case Bstringlss:
4015b3c0
GM
1502 {
1503 Lisp_Object v1;
bf1de43e 1504 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1505 v1 = POP;
1506 TOP = Fstring_lessp (TOP, v1);
bf1de43e 1507 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1508 break;
1509 }
36f7ba0a
JB
1510
1511 case Bequal:
4015b3c0
GM
1512 {
1513 Lisp_Object v1;
1514 v1 = POP;
1515 TOP = Fequal (TOP, v1);
1516 break;
1517 }
36f7ba0a
JB
1518
1519 case Bnthcdr:
4015b3c0
GM
1520 {
1521 Lisp_Object v1;
bf1de43e 1522 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1523 v1 = POP;
1524 TOP = Fnthcdr (TOP, v1);
bf1de43e 1525 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1526 break;
1527 }
36f7ba0a
JB
1528
1529 case Belt:
4015b3c0
GM
1530 {
1531 Lisp_Object v1, v2;
1532 if (CONSP (TOP))
1533 {
1534 /* Exchange args and then do nth. */
bf1de43e 1535 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1536 v2 = POP;
1537 v1 = TOP;
b7826503 1538 CHECK_NUMBER (v2);
f5941bf8 1539 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1540 op = XINT (v2);
1541 immediate_quit = 1;
1542 while (--op >= 0)
1543 {
1544 if (CONSP (v1))
1545 v1 = XCDR (v1);
1546 else if (!NILP (v1))
1547 {
1548 immediate_quit = 0;
892a8eb5 1549 wrong_type_argument (Qlistp, v1);
4015b3c0
GM
1550 }
1551 }
1552 immediate_quit = 0;
fa9aabf6
GM
1553 if (CONSP (v1))
1554 TOP = XCAR (v1);
1555 else if (NILP (v1))
1556 TOP = Qnil;
1557 else
892a8eb5 1558 wrong_type_argument (Qlistp, v1);
4015b3c0
GM
1559 }
1560 else
1561 {
bf1de43e 1562 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1563 v1 = POP;
1564 TOP = Felt (TOP, v1);
bf1de43e 1565 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1566 }
1567 break;
1568 }
36f7ba0a
JB
1569
1570 case Bmember:
4015b3c0
GM
1571 {
1572 Lisp_Object v1;
bf1de43e 1573 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1574 v1 = POP;
1575 TOP = Fmember (TOP, v1);
bf1de43e 1576 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1577 break;
1578 }
36f7ba0a
JB
1579
1580 case Bassq:
4015b3c0
GM
1581 {
1582 Lisp_Object v1;
bf1de43e 1583 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1584 v1 = POP;
1585 TOP = Fassq (TOP, v1);
bf1de43e 1586 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1587 break;
1588 }
36f7ba0a
JB
1589
1590 case Bnreverse:
bf1de43e 1591 BEFORE_POTENTIAL_GC ();
36f7ba0a 1592 TOP = Fnreverse (TOP);
bf1de43e 1593 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1594 break;
1595
1596 case Bsetcar:
4015b3c0
GM
1597 {
1598 Lisp_Object v1;
bf1de43e 1599 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1600 v1 = POP;
1601 TOP = Fsetcar (TOP, v1);
bf1de43e 1602 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1603 break;
1604 }
36f7ba0a
JB
1605
1606 case Bsetcdr:
4015b3c0
GM
1607 {
1608 Lisp_Object v1;
bf1de43e 1609 BEFORE_POTENTIAL_GC ();
4015b3c0
GM
1610 v1 = POP;
1611 TOP = Fsetcdr (TOP, v1);
bf1de43e 1612 AFTER_POTENTIAL_GC ();
4015b3c0
GM
1613 break;
1614 }
36f7ba0a
JB
1615
1616 case Bcar_safe:
4015b3c0
GM
1617 {
1618 Lisp_Object v1;
1619 v1 = TOP;
1620 if (CONSP (v1))
1621 TOP = XCAR (v1);
1622 else
1623 TOP = Qnil;
1624 break;
1625 }
36f7ba0a
JB
1626
1627 case Bcdr_safe:
4015b3c0
GM
1628 {
1629 Lisp_Object v1;
1630 v1 = TOP;
1631 if (CONSP (v1))
1632 TOP = XCDR (v1);
1633 else
1634 TOP = Qnil;
1635 break;
1636 }
36f7ba0a
JB
1637
1638 case Bnconc:
bf1de43e 1639 BEFORE_POTENTIAL_GC ();
63639d44 1640 DISCARD (1);
36f7ba0a 1641 TOP = Fnconc (2, &TOP);
bf1de43e 1642 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1643 break;
1644
1645 case Bnumberp:
63639d44 1646 TOP = (NUMBERP (TOP) ? Qt : Qnil);
36f7ba0a
JB
1647 break;
1648
1649 case Bintegerp:
617bd3f6 1650 TOP = INTEGERP (TOP) ? Qt : Qnil;
36f7ba0a
JB
1651 break;
1652
1653#ifdef BYTE_CODE_SAFE
1654 case Bset_mark:
f5941bf8 1655 BEFORE_POTENTIAL_GC ();
36f7ba0a 1656 error ("set-mark is an obsolete bytecode");
f5941bf8 1657 AFTER_POTENTIAL_GC ();
36f7ba0a
JB
1658 break;
1659 case Bscan_buffer:
f5941bf8 1660 BEFORE_POTENTIAL_GC ();
36f7ba0a 1661 error ("scan-buffer is an obsolete bytecode");
f5941bf8 1662 AFTER_POTENTIAL_GC ();
36f7ba0a 1663 break;
36f7ba0a
JB
1664#endif
1665
c96d71f7
RS
1666 case 0:
1667 abort ();
1668
1669 case 255:
36f7ba0a
JB
1670 default:
1671#ifdef BYTE_CODE_SAFE
1672 if (op < Bconstant)
f5941bf8 1673 {
cc94f3b2 1674 abort ();
f5941bf8 1675 }
36f7ba0a 1676 if ((op -= Bconstant) >= const_length)
f5941bf8 1677 {
cc94f3b2 1678 abort ();
f5941bf8 1679 }
36f7ba0a
JB
1680 PUSH (vectorp[op]);
1681#else
1682 PUSH (vectorp[op - Bconstant]);
1683#endif
1684 }
1685 }
1686
1687 exit:
7ca1e8b7
GM
1688
1689 byte_stack_list = byte_stack_list->next;
1690
36f7ba0a 1691 /* Binds and unbinds are supposed to be compiled balanced. */
aed13378 1692 if (SPECPDL_INDEX () != count)
36f7ba0a
JB
1693#ifdef BYTE_CODE_SAFE
1694 error ("binding stack not balanced (serious byte compiler bug)");
1695#else
1696 abort ();
1697#endif
8e11578b 1698
4015b3c0 1699 return result;
36f7ba0a
JB
1700}
1701
dfcf069d 1702void
36f7ba0a
JB
1703syms_of_bytecode ()
1704{
1705 Qbytecode = intern ("byte-code");
1706 staticpro (&Qbytecode);
1707
1708 defsubr (&Sbyte_code);
1709
1710#ifdef BYTE_CODE_METER
1711
1712 DEFVAR_LISP ("byte-code-meter", &Vbyte_code_meter,
39f624fa
PJ
1713 doc: /* A vector of vectors which holds a histogram of byte-code usage.
1714\(aref (aref byte-code-meter 0) CODE) indicates how many times the byte
1715opcode CODE has been executed.
1716\(aref (aref byte-code-meter CODE1) CODE2), where CODE1 is not 0,
1717indicates how many times the byte opcodes CODE1 and CODE2 have been
1718executed in succession. */);
8e11578b 1719
63639d44 1720 DEFVAR_BOOL ("byte-metering-on", &byte_metering_on,
39f624fa
PJ
1721 doc: /* If non-nil, keep profiling information on byte code usage.
1722The variable byte-code-meter indicates how often each byte opcode is used.
1723If a symbol has a property named `byte-code-meter' whose value is an
1724integer, it is incremented each time that symbol's function is called. */);
36f7ba0a
JB
1725
1726 byte_metering_on = 0;
63639d44
JB
1727 Vbyte_code_meter = Fmake_vector (make_number (256), make_number (0));
1728 Qbyte_code_meter = intern ("byte-code-meter");
1729 staticpro (&Qbyte_code_meter);
36f7ba0a
JB
1730 {
1731 int i = 256;
1732 while (i--)
63639d44
JB
1733 XVECTOR (Vbyte_code_meter)->contents[i] =
1734 Fmake_vector (make_number (256), make_number (0));
36f7ba0a
JB
1735 }
1736#endif
1737}
ab5796a9
MB
1738
1739/* arch-tag: b9803b6f-1ed6-4190-8adf-33fd3a9d10e9
1740 (do not change this comment) */