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