Commit | Line | Data |
---|---|---|
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 | |
4 | This file is part of GNU Emacs. | |
5 | ||
9ec0b715 | 6 | GNU Emacs is free software: you can redistribute it and/or modify |
36f7ba0a | 7 | it under the terms of the GNU General Public License as published by |
9ec0b715 GM |
8 | the Free Software Foundation, either version 3 of the License, or |
9 | (at your option) any later version. | |
36f7ba0a JB |
10 | |
11 | GNU Emacs is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
9ec0b715 | 17 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ |
36f7ba0a | 18 | |
9ec0b715 | 19 | /* |
63639d44 | 20 | hacked 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 | ||
30 | by 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 | 60 | Lisp_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 | ||
86 | Lisp_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 | ||
236 | struct 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 | ||
266 | struct byte_stack *byte_stack_list; | |
267 | ||
4015b3c0 | 268 | \f |
7ca1e8b7 GM |
269 | /* Mark objects on byte_stack_list. Called during GC. */ |
270 | ||
271 | void | |
971de7fb | 272 | mark_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 | 300 | void |
971de7fb | 301 | unmark_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 | 397 | DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0, |
39f624fa PJ |
398 | doc: /* Function used internally in byte-compiled code. |
399 | The first argument, BYTESTR, is a string of byte code; | |
400 | the second, VECTOR, a vector of constants; | |
401 | the third, MAXDEPTH, the maximum stack depth used in this function. | |
402 | If 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 | 1676 | void |
971de7fb | 1677 | syms_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 | |
1689 | opcode CODE has been executed. | |
1690 | \(aref (aref byte-code-meter CODE1) CODE2), where CODE1 is not 0, | |
1691 | indicates how many times the byte opcodes CODE1 and CODE2 have been | |
1692 | executed 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. |
1696 | The variable byte-code-meter indicates how often each byte opcode is used. | |
1697 | If a symbol has a property named `byte-code-meter' whose value is an | |
1698 | integer, 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 | } |