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