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