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