X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/97d44922da3c22b3973f95892bfa2ee4afc0ceac..3e71e4379ce7b53afe51ead4c94e6bb016bc6e7a:/src/bytecode.c diff --git a/src/bytecode.c b/src/bytecode.c index 55789b41ad..1b02c60c61 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -1,13 +1,13 @@ /* Execution of byte code produced by bytecomp.el. - Copyright (C) 1985-1988, 1993, 2000-2015 Free Software Foundation, + Copyright (C) 1985-1988, 1993, 2000-2016 Free Software Foundation, Inc. This file is part of GNU Emacs. GNU Emacs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. +the Free Software Foundation, either version 3 of the License, or (at +your option) any later version. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -17,22 +17,6 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see . */ -/* -hacked on by jwz@lucid.com 17-jun-91 - o added a compile-time switch to turn on simple sanity checking; - o put back the obsolete byte-codes for error-detection; - o added a new instruction, unbind_all, which I will use for - tail-recursion elimination; - o made temp_output_buffer_show be called with the right number - of args; - o made the new bytecodes be called with args in the right order; - o added metering support. - -by Hallvard: - o added relative jump instructions; - o all conditionals now only do QUIT if they jump. - */ - #include #include "lisp.h" @@ -48,6 +32,11 @@ by Hallvard: #include "xterm.h" #endif +/* Work around GCC bug 54561. */ +#if GNUC_PREREQ (4, 3, 0) +# pragma GCC diagnostic ignored "-Wclobbered" +#endif + /* * define BYTE_CODE_SAFE to enable some minor sanity checking (useful for * debugging the byte compiler...) @@ -294,9 +283,6 @@ enum byte_code_op Bset_mark = 0163, /* this loser is no longer generated as of v18 */ #endif }; - -/* Whether to maintain a `top' and `bottom' field in the stack frame. */ -#define BYTE_MAINTAIN_TOP (BYTE_CODE_SAFE || BYTE_MARK_STACK) /* Structure describing a value stack used during byte-code execution in Fbyte_code. */ @@ -307,24 +293,11 @@ struct byte_stack and is relocated when that string is relocated. */ const unsigned char *pc; - /* Top and bottom of stack. The bottom points to an area of memory - allocated with alloca in Fbyte_code. */ -#if BYTE_MAINTAIN_TOP - Lisp_Object *top, *bottom; -#endif - /* The string containing the byte-code, and its current address. - Storing this here protects it from GC because mark_byte_stack - marks it. */ + Storing this here protects it from GC. */ Lisp_Object byte_string; const unsigned char *byte_string_start; -#if BYTE_MARK_STACK - /* The vector of constants used during byte-code execution. Storing - this here protects it from GC because mark_byte_stack marks it. */ - Lisp_Object constants; -#endif - /* Next entry in byte_stack_list. */ struct byte_stack *next; }; @@ -332,46 +305,16 @@ struct byte_stack /* A list of currently active byte-code execution value stacks. Fbyte_code adds an entry to the head of this list before it starts processing byte-code, and it removes the entry again when it is - done. Signaling an error truncates the list analogous to - gcprolist. */ + done. Signaling an error truncates the list. */ struct byte_stack *byte_stack_list; -/* Mark objects on byte_stack_list. Called during GC. */ - -#if BYTE_MARK_STACK -void -mark_byte_stack (void) -{ - struct byte_stack *stack; - Lisp_Object *obj; - - for (stack = byte_stack_list; stack; stack = stack->next) - { - /* If STACK->top is null here, this means there's an opcode in - Fbyte_code that wasn't expected to GC, but did. To find out - which opcode this is, record the value of `stack', and walk - up the stack in a debugger, stopping in frames of Fbyte_code. - The culprit is found in the frame of Fbyte_code where the - address of its local variable `stack' is equal to the - recorded value of `stack' here. */ - eassert (stack->top); - - for (obj = stack->bottom; obj <= stack->top; ++obj) - mark_object (*obj); - - mark_object (stack->byte_string); - mark_object (stack->constants); - } -} -#endif - -/* Unmark objects in the stacks on byte_stack_list. Relocate program - counters. Called when GC has completed. */ +/* Relocate program counters in the stacks on byte_stack_list. Called + when GC has completed. */ void -unmark_byte_stack (void) +relocate_byte_stack (void) { struct byte_stack *stack; @@ -400,12 +343,10 @@ unmark_byte_stack (void) #define FETCH2 (op = FETCH, op + (FETCH << 8)) -/* Push x onto the execution stack. This used to be #define PUSH(x) - (*++stackp = (x)) This oddity is necessary because Alliant can't be - bothered to compile the preincrement operator properly, as of 4/91. - -JimB */ +/* Push X onto the execution stack. The expression X should not + contain TOP, to avoid competing side effects. */ -#define PUSH(x) (top++, *top = (x)) +#define PUSH(x) (*++top = (x)) /* Pop a value off the execution stack. */ @@ -420,27 +361,6 @@ unmark_byte_stack (void) #define TOP (*top) -/* Actions that must be performed before and after calling a function - that might GC. */ - -#if !BYTE_MAINTAIN_TOP -#define BEFORE_POTENTIAL_GC() ((void)0) -#define AFTER_POTENTIAL_GC() ((void)0) -#else -#define BEFORE_POTENTIAL_GC() stack.top = top -#define AFTER_POTENTIAL_GC() stack.top = NULL -#endif - -/* Garbage collect if we have consed enough since the last time. - We do this at every branch, to avoid loops that never GC. */ - -#define MAYBE_GC() \ - do { \ - BEFORE_POTENTIAL_GC (); \ - maybe_gc (); \ - AFTER_POTENTIAL_GC (); \ - } while (0) - /* Check for jumping out of range. */ #ifdef BYTE_CODE_SAFE @@ -463,11 +383,9 @@ unmark_byte_stack (void) { \ Lisp_Object flag = Vquit_flag; \ Vquit_flag = Qnil; \ - BEFORE_POTENTIAL_GC (); \ if (EQ (Vthrow_on_input, flag)) \ Fthrow (Vthrow_on_input, Qt); \ Fsignal (Qquit, Qnil); \ - AFTER_POTENTIAL_GC (); \ } \ else if (pending_signals) \ process_pending_signals (); \ @@ -554,16 +472,9 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, stack.byte_string = bytestr; stack.pc = stack.byte_string_start = SDATA (bytestr); -#if BYTE_MARK_STACK - stack.constants = vector; -#endif if (MAX_ALLOCA / word_size <= XFASTINT (maxdepth)) memory_full (SIZE_MAX); top = alloca ((XFASTINT (maxdepth) + 1) * sizeof *top); -#if BYTE_MAINTAIN_TOP - stack.bottom = top + 1; - stack.top = NULL; -#endif stack.next = byte_stack_list; byte_stack_list = &stack; @@ -676,7 +587,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, the table clearer. */ #define LABEL(OP) [OP] = &&insn_ ## OP -#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) +#if GNUC_PREREQ (4, 6, 0) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Woverride-init" #elif defined __clang__ @@ -695,7 +606,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, #undef DEFINE }; -#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) || defined __clang__ +#if GNUC_PREREQ (4, 6, 0) || defined __clang__ # pragma GCC diagnostic pop #endif @@ -732,16 +643,12 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, || (v2 = SYMBOL_VAL (XSYMBOL (v1)), EQ (v2, Qunbound))) { - BEFORE_POTENTIAL_GC (); v2 = Fsymbol_value (v1); - AFTER_POTENTIAL_GC (); } } else { - BEFORE_POTENTIAL_GC (); v2 = Fsymbol_value (v1); - AFTER_POTENTIAL_GC (); } PUSH (v2); NEXT; @@ -750,7 +657,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, CASE (Bgotoifnil): { Lisp_Object v1; - MAYBE_GC (); + maybe_gc (); op = FETCH2; v1 = POP; if (NILP (v1)) @@ -772,7 +679,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, TOP = Qnil; else { - BEFORE_POTENTIAL_GC (); wrong_type_argument (Qlistp, v1); } NEXT; @@ -789,10 +695,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, CASE (Bmemq): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Fmemq (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } @@ -806,7 +710,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, TOP = Qnil; else { - BEFORE_POTENTIAL_GC (); wrong_type_argument (Qlistp, v1); } NEXT; @@ -842,9 +745,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, SET_SYMBOL_VAL (XSYMBOL (sym), val); else { - BEFORE_POTENTIAL_GC (); set_internal (sym, val, Qnil, 0); - AFTER_POTENTIAL_GC (); } } (void) POP; @@ -877,9 +778,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, op -= Bvarbind; varbind: /* Specbind can signal and thus GC. */ - BEFORE_POTENTIAL_GC (); specbind (vectorp[op], POP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bcall6): @@ -899,7 +798,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, op -= Bcall; docall: { - BEFORE_POTENTIAL_GC (); DISCARD (op); #ifdef BYTE_CODE_METER if (byte_metering_on && SYMBOLP (TOP)) @@ -917,7 +815,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, } #endif TOP = Ffuncall (op + 1, &TOP); - AFTER_POTENTIAL_GC (); NEXT; } @@ -937,21 +834,17 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, CASE (Bunbind5): op -= Bunbind; dounbind: - BEFORE_POTENTIAL_GC (); unbind_to (SPECPDL_INDEX () - op, Qnil); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bunbind_all): /* Obsolete. Never used. */ /* To unbind back to the beginning of this frame. Not used yet, but will be needed for tail-recursion elimination. */ - BEFORE_POTENTIAL_GC (); unbind_to (count, Qnil); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bgoto): - MAYBE_GC (); + maybe_gc (); BYTE_CODE_QUIT; op = FETCH2; /* pc = FETCH2 loses since FETCH2 contains pc++ */ CHECK_RANGE (op); @@ -961,7 +854,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, CASE (Bgotoifnonnil): { Lisp_Object v1; - MAYBE_GC (); + maybe_gc (); op = FETCH2; v1 = POP; if (!NILP (v1)) @@ -974,7 +867,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, } CASE (Bgotoifnilelsepop): - MAYBE_GC (); + maybe_gc (); op = FETCH2; if (NILP (TOP)) { @@ -986,7 +879,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, NEXT; CASE (Bgotoifnonnilelsepop): - MAYBE_GC (); + maybe_gc (); op = FETCH2; if (!NILP (TOP)) { @@ -998,7 +891,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, NEXT; CASE (BRgoto): - MAYBE_GC (); + maybe_gc (); BYTE_CODE_QUIT; stack.pc += (int) *stack.pc - 127; NEXT; @@ -1006,7 +899,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, CASE (BRgotoifnil): { Lisp_Object v1; - MAYBE_GC (); + maybe_gc (); v1 = POP; if (NILP (v1)) { @@ -1020,7 +913,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, CASE (BRgotoifnonnil): { Lisp_Object v1; - MAYBE_GC (); + maybe_gc (); v1 = POP; if (!NILP (v1)) { @@ -1032,7 +925,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, } CASE (BRgotoifnilelsepop): - MAYBE_GC (); + maybe_gc (); op = *stack.pc++; if (NILP (TOP)) { @@ -1043,7 +936,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, NEXT; CASE (BRgotoifnonnilelsepop): - MAYBE_GC (); + maybe_gc (); op = *stack.pc++; if (!NILP (TOP)) { @@ -1080,10 +973,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, ptrdiff_t count1 = SPECPDL_INDEX (); record_unwind_protect (restore_window_configuration, Fcurrent_window_configuration (Qnil)); - BEFORE_POTENTIAL_GC (); TOP = Fprogn (TOP); unbind_to (count1, TOP); - AFTER_POTENTIAL_GC (); NEXT; } @@ -1095,10 +986,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, CASE (Bcatch): /* Obsolete since 24.4. */ { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = internal_catch (TOP, eval_sub, v1); - AFTER_POTENTIAL_GC (); NEXT; } @@ -1106,17 +995,13 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, type = CATCHER; goto pushhandler; CASE (Bpushconditioncase): /* New in 24.4. */ + type = CONDITION_CASE; + pushhandler: { - struct handler *c; - Lisp_Object tag; - int dest; - - type = CONDITION_CASE; - pushhandler: - tag = POP; - dest = FETCH2; + Lisp_Object tag = POP; + int dest = FETCH2; - PUSH_HANDLER (c, tag, type); + struct handler *c = push_handler (tag, type); c->bytecode_dest = dest; c->bytecode_top = top; @@ -1158,30 +1043,24 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, Lisp_Object handlers, body; handlers = POP; body = POP; - BEFORE_POTENTIAL_GC (); TOP = internal_lisp_condition_case (TOP, body, handlers); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Btemp_output_buffer_setup): /* Obsolete since 24.1. */ - BEFORE_POTENTIAL_GC (); CHECK_STRING (TOP); temp_output_buffer_setup (SSDATA (TOP)); - AFTER_POTENTIAL_GC (); TOP = Vstandard_output; NEXT; CASE (Btemp_output_buffer_show): /* Obsolete since 24.1. */ { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; temp_output_buffer_show (TOP); TOP = v1; /* pop binding of standard-output */ unbind_to (SPECPDL_INDEX () - 1, Qnil); - AFTER_POTENTIAL_GC (); NEXT; } @@ -1189,7 +1068,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, { Lisp_Object v1, v2; EMACS_INT n; - BEFORE_POTENTIAL_GC (); v1 = POP; v2 = TOP; CHECK_NUMBER (v2); @@ -1199,7 +1077,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, v1 = XCDR (v1); immediate_quit = 0; TOP = CAR (v1); - AFTER_POTENTIAL_GC (); NEXT; } @@ -1260,110 +1137,84 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, NEXT; CASE (Blength): - BEFORE_POTENTIAL_GC (); TOP = Flength (TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Baref): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Faref (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Baset): { Lisp_Object v1, v2; - BEFORE_POTENTIAL_GC (); v2 = POP; v1 = POP; TOP = Faset (TOP, v1, v2); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bsymbol_value): - BEFORE_POTENTIAL_GC (); TOP = Fsymbol_value (TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bsymbol_function): - BEFORE_POTENTIAL_GC (); TOP = Fsymbol_function (TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bset): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Fset (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bfset): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Ffset (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bget): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Fget (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bsubstring): { Lisp_Object v1, v2; - BEFORE_POTENTIAL_GC (); v2 = POP; v1 = POP; TOP = Fsubstring (TOP, v1, v2); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bconcat2): - BEFORE_POTENTIAL_GC (); DISCARD (1); TOP = Fconcat (2, &TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bconcat3): - BEFORE_POTENTIAL_GC (); DISCARD (2); TOP = Fconcat (3, &TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bconcat4): - BEFORE_POTENTIAL_GC (); DISCARD (3); TOP = Fconcat (4, &TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (BconcatN): op = FETCH; - BEFORE_POTENTIAL_GC (); DISCARD (op - 1); TOP = Fconcat (op, &TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bsub1): @@ -1377,9 +1228,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, } else { - BEFORE_POTENTIAL_GC (); TOP = Fsub1 (v1); - AFTER_POTENTIAL_GC (); } NEXT; } @@ -1395,9 +1244,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, } else { - BEFORE_POTENTIAL_GC (); TOP = Fadd1 (v1); - AFTER_POTENTIAL_GC (); } NEXT; } @@ -1405,11 +1252,9 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, CASE (Beqlsign): { Lisp_Object v1, v2; - BEFORE_POTENTIAL_GC (); v2 = POP; v1 = TOP; CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (v1); CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (v2); - AFTER_POTENTIAL_GC (); if (FLOATP (v1) || FLOATP (v2)) { double f1, f2; @@ -1426,48 +1271,38 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, CASE (Bgtr): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = arithcompare (TOP, v1, ARITH_GRTR); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Blss): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = arithcompare (TOP, v1, ARITH_LESS); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bleq): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = arithcompare (TOP, v1, ARITH_LESS_OR_EQUAL); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bgeq): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = arithcompare (TOP, v1, ARITH_GRTR_OR_EQUAL); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bdiff): - BEFORE_POTENTIAL_GC (); DISCARD (1); TOP = Fminus (2, &TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bnegate): @@ -1481,55 +1316,41 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, } else { - BEFORE_POTENTIAL_GC (); TOP = Fminus (1, &TOP); - AFTER_POTENTIAL_GC (); } NEXT; } CASE (Bplus): - BEFORE_POTENTIAL_GC (); DISCARD (1); TOP = Fplus (2, &TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bmax): - BEFORE_POTENTIAL_GC (); DISCARD (1); TOP = Fmax (2, &TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bmin): - BEFORE_POTENTIAL_GC (); DISCARD (1); TOP = Fmin (2, &TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bmult): - BEFORE_POTENTIAL_GC (); DISCARD (1); TOP = Ftimes (2, &TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bquo): - BEFORE_POTENTIAL_GC (); DISCARD (1); TOP = Fquo (2, &TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Brem): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Frem (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } @@ -1542,23 +1363,17 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, } CASE (Bgoto_char): - BEFORE_POTENTIAL_GC (); TOP = Fgoto_char (TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Binsert): - BEFORE_POTENTIAL_GC (); TOP = Finsert (1, &TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (BinsertN): op = FETCH; - BEFORE_POTENTIAL_GC (); DISCARD (op - 1); TOP = Finsert (op, &TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bpoint_max): @@ -1578,17 +1393,13 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, } CASE (Bchar_after): - BEFORE_POTENTIAL_GC (); TOP = Fchar_after (TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bfollowing_char): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = Ffollowing_char (); - AFTER_POTENTIAL_GC (); PUSH (v1); NEXT; } @@ -1596,9 +1407,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, CASE (Bpreceding_char): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = Fprevious_char (); - AFTER_POTENTIAL_GC (); PUSH (v1); NEXT; } @@ -1606,17 +1415,13 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, CASE (Bcurrent_column): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); XSETFASTINT (v1, current_column ()); - AFTER_POTENTIAL_GC (); PUSH (v1); NEXT; } CASE (Bindent_to): - BEFORE_POTENTIAL_GC (); TOP = Findent_to (TOP, Qnil); - AFTER_POTENTIAL_GC (); NEXT; CASE (Beolp): @@ -1640,62 +1445,46 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, NEXT; CASE (Bset_buffer): - BEFORE_POTENTIAL_GC (); TOP = Fset_buffer (TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Binteractive_p): /* Obsolete since 24.1. */ - BEFORE_POTENTIAL_GC (); PUSH (call0 (intern ("interactive-p"))); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bforward_char): - BEFORE_POTENTIAL_GC (); TOP = Fforward_char (TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bforward_word): - BEFORE_POTENTIAL_GC (); TOP = Fforward_word (TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bskip_chars_forward): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Fskip_chars_forward (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bskip_chars_backward): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Fskip_chars_backward (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bforward_line): - BEFORE_POTENTIAL_GC (); TOP = Fforward_line (TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bchar_syntax): { int c; - BEFORE_POTENTIAL_GC (); CHECK_CHARACTER (TOP); - AFTER_POTENTIAL_GC (); c = XFASTINT (TOP); if (NILP (BVAR (current_buffer, enable_multibyte_characters))) MAKE_CHAR_MULTIBYTE (c); @@ -1706,97 +1495,73 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, CASE (Bbuffer_substring): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Fbuffer_substring (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bdelete_region): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Fdelete_region (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bnarrow_to_region): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Fnarrow_to_region (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bwiden): - BEFORE_POTENTIAL_GC (); PUSH (Fwiden ()); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bend_of_line): - BEFORE_POTENTIAL_GC (); TOP = Fend_of_line (TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bset_marker): { Lisp_Object v1, v2; - BEFORE_POTENTIAL_GC (); v1 = POP; v2 = POP; TOP = Fset_marker (TOP, v2, v1); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bmatch_beginning): - BEFORE_POTENTIAL_GC (); TOP = Fmatch_beginning (TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bmatch_end): - BEFORE_POTENTIAL_GC (); TOP = Fmatch_end (TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bupcase): - BEFORE_POTENTIAL_GC (); TOP = Fupcase (TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bdowncase): - BEFORE_POTENTIAL_GC (); TOP = Fdowncase (TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bstringeqlsign): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Fstring_equal (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bstringlss): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Fstring_lessp (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } @@ -1811,10 +1576,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, CASE (Bnthcdr): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Fnthcdr (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } @@ -1825,11 +1588,9 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, { /* Exchange args and then do nth. */ EMACS_INT n; - BEFORE_POTENTIAL_GC (); v2 = POP; v1 = TOP; CHECK_NUMBER (v2); - AFTER_POTENTIAL_GC (); n = XINT (v2); immediate_quit = 1; while (--n >= 0 && CONSP (v1)) @@ -1839,10 +1600,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, } else { - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Felt (TOP, v1); - AFTER_POTENTIAL_GC (); } NEXT; } @@ -1850,46 +1609,36 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, CASE (Bmember): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Fmember (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bassq): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Fassq (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bnreverse): - BEFORE_POTENTIAL_GC (); TOP = Fnreverse (TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bsetcar): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Fsetcar (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } CASE (Bsetcdr): { Lisp_Object v1; - BEFORE_POTENTIAL_GC (); v1 = POP; TOP = Fsetcdr (TOP, v1); - AFTER_POTENTIAL_GC (); NEXT; } @@ -1910,10 +1659,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, } CASE (Bnconc): - BEFORE_POTENTIAL_GC (); DISCARD (1); TOP = Fnconc (2, &TOP); - AFTER_POTENTIAL_GC (); NEXT; CASE (Bnumberp): @@ -1930,14 +1677,10 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, interpreter. */ case Bset_mark: - BEFORE_POTENTIAL_GC (); error ("set-mark is an obsolete bytecode"); - AFTER_POTENTIAL_GC (); break; case Bscan_buffer: - BEFORE_POTENTIAL_GC (); error ("scan-buffer is an obsolete bytecode"); - AFTER_POTENTIAL_GC (); break; #endif @@ -2030,6 +1773,20 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, return result; } +/* `args_template' has the same meaning as in exec_byte_code() above. */ +Lisp_Object +get_byte_code_arity (Lisp_Object args_template) +{ + eassert (NATNUMP (args_template)); + EMACS_INT at = XINT (args_template); + bool rest = (at & 128) != 0; + int mandatory = at & 127; + EMACS_INT nonrest = at >> 8; + + return Fcons (make_number (mandatory), + rest ? Qmany : make_number (nonrest)); +} + void syms_of_bytecode (void) {