summaryrefslogtreecommitdiff
path: root/src/bytecode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bytecode.c')
-rw-r--r--src/bytecode.c1007
1 files changed, 235 insertions, 772 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index fa942fc4e1b..a64bc171d14 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -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 <http://www.gnu.org/licenses/>. */
-/*
-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 <config.h>
#include "lisp.h"
@@ -43,33 +27,35 @@ by Hallvard:
#include "syntax.h"
#include "window.h"
-#ifdef CHECK_FRAME_FONT
-#include "frame.h"
-#include "xterm.h"
+/* Work around GCC bug 54561. */
+#if GNUC_PREREQ (4, 3, 0)
+# pragma GCC diagnostic ignored "-Wclobbered"
+#endif
+
+/* Define BYTE_CODE_SAFE true to enable some minor sanity checking,
+ useful for debugging the byte compiler. It defaults to false. */
+
+#ifndef BYTE_CODE_SAFE
+# define BYTE_CODE_SAFE false
#endif
-/*
- * define BYTE_CODE_SAFE to enable some minor sanity checking (useful for
- * debugging the byte compiler...)
- *
- * define BYTE_CODE_METER to enable generation of a byte-op usage histogram.
- */
-/* #define BYTE_CODE_SAFE */
+/* Define BYTE_CODE_METER to generate a byte-op usage histogram. */
/* #define BYTE_CODE_METER */
/* If BYTE_CODE_THREADED is defined, then the interpreter will be
indirect threaded, using GCC's computed goto extension. This code,
as currently implemented, is incompatible with BYTE_CODE_SAFE and
BYTE_CODE_METER. */
-#if (defined __GNUC__ && !defined __STRICT_ANSI__ \
- && !defined BYTE_CODE_SAFE && !defined BYTE_CODE_METER)
+#if (defined __GNUC__ && !defined __STRICT_ANSI__ && !defined __CHKP__ \
+ && !BYTE_CODE_SAFE && !defined BYTE_CODE_METER)
#define BYTE_CODE_THREADED
#endif
#ifdef BYTE_CODE_METER
-#define METER_2(code1, code2) AREF (AREF (Vbyte_code_meter, code1), code2)
+#define METER_2(code1, code2) \
+ (*aref_addr (AREF (Vbyte_code_meter, code1), code2))
#define METER_1(code) METER_2 (0, code)
#define METER_CODE(last_code, this_code) \
@@ -289,87 +275,25 @@ enum byte_code_op
BYTE_CODES
#undef DEFINE
-#ifdef BYTE_CODE_SAFE
+#if BYTE_CODE_SAFE
Bscan_buffer = 0153, /* No longer generated as of v18. */
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
-
-/* Structure describing a value stack used during byte-code execution
- in Fbyte_code. */
-
-struct byte_stack
-{
- /* Program counter. This points into the byte_string below
- 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. */
- Lisp_Object byte_string;
- const unsigned char *byte_string_start;
-
- /* Next entry in byte_stack_list. */
- struct byte_stack *next;
-};
-
-/* 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. */
-
-struct byte_stack *byte_stack_list;
-
-
-/* Relocate program counters in the stacks on byte_stack_list. Called
- when GC has completed. */
-
-void
-relocate_byte_stack (void)
-{
- struct byte_stack *stack;
-
- for (stack = byte_stack_list; stack; stack = stack->next)
- {
- if (stack->byte_string_start != SDATA (stack->byte_string))
- {
- ptrdiff_t offset = stack->pc - stack->byte_string_start;
- stack->byte_string_start = SDATA (stack->byte_string);
- stack->pc = stack->byte_string_start + offset;
- }
- }
-}
-
/* Fetch the next byte from the bytecode stream. */
-#ifdef BYTE_CODE_SAFE
-#define FETCH (eassert (stack.byte_string_start == SDATA (stack.byte_string)), *stack.pc++)
-#else
-#define FETCH *stack.pc++
-#endif
+#define FETCH (*pc++)
/* Fetch two bytes from the bytecode stream and make a 16-bit number
out of them. */
#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. */
@@ -384,60 +308,6 @@ relocate_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
-
-#define CHECK_RANGE(ARG) \
- if (ARG >= bytestr_length) emacs_abort ()
-
-#else /* not BYTE_CODE_SAFE */
-
-#define CHECK_RANGE(ARG)
-
-#endif /* not BYTE_CODE_SAFE */
-
-/* A version of the QUIT macro which makes sure that the stack top is
- set before signaling `quit'. */
-
-#define BYTE_CODE_QUIT \
- do { \
- if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \
- { \
- 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 (); \
- } while (0)
-
-
DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0,
doc: /* Function used internally in byte-compiled code.
The first argument, BYTESTR, is a string of byte code;
@@ -467,41 +337,15 @@ Lisp_Object
exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
Lisp_Object args_template, ptrdiff_t nargs, Lisp_Object *args)
{
- ptrdiff_t count = SPECPDL_INDEX ();
#ifdef BYTE_CODE_METER
int volatile this_op = 0;
- int prev_op;
-#endif
- int op;
- /* Lisp_Object v1, v2; */
- Lisp_Object *vectorp;
-#ifdef BYTE_CODE_SAFE
- ptrdiff_t const_length;
- Lisp_Object *stacke;
- ptrdiff_t bytestr_length;
-#endif
- struct byte_stack stack;
- Lisp_Object *top;
- Lisp_Object result;
- enum handlertype type;
-
-#if 0 /* CHECK_FRAME_FONT */
- {
- struct frame *f = SELECTED_FRAME ();
- if (FRAME_X_P (f)
- && FRAME_FONT (f)->direction != 0
- && FRAME_FONT (f)->direction != 1)
- emacs_abort ();
- }
#endif
CHECK_STRING (bytestr);
CHECK_VECTOR (vector);
CHECK_NATNUM (maxdepth);
-#ifdef BYTE_CODE_SAFE
- const_length = ASIZE (vector);
-#endif
+ ptrdiff_t const_length = ASIZE (vector);
if (STRING_MULTIBYTE (bytestr))
/* BYTESTR must have been produced by Emacs 20.2 or the earlier
@@ -511,90 +355,59 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
convert them back to the originally intended unibyte form. */
bytestr = Fstring_as_unibyte (bytestr);
-#ifdef BYTE_CODE_SAFE
- bytestr_length = SBYTES (bytestr);
-#endif
- vectorp = XVECTOR (vector)->contents;
-
- stack.byte_string = bytestr;
- stack.pc = stack.byte_string_start = SDATA (bytestr);
- 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;
-
-#ifdef BYTE_CODE_SAFE
- stacke = stack.bottom - 1 + XFASTINT (maxdepth);
-#endif
+ ptrdiff_t bytestr_length = SBYTES (bytestr);
+ Lisp_Object *vectorp = XVECTOR (vector)->contents;
+
+ unsigned char quitcounter = 1;
+ EMACS_INT stack_items = XFASTINT (maxdepth) + 1;
+ USE_SAFE_ALLOCA;
+ Lisp_Object *stack_base;
+ SAFE_ALLOCA_LISP_EXTRA (stack_base, stack_items, bytestr_length);
+ Lisp_Object *stack_lim = stack_base + stack_items;
+ Lisp_Object *top = stack_base;
+ memcpy (stack_lim, SDATA (bytestr), bytestr_length);
+ void *void_stack_lim = stack_lim;
+ unsigned char const *bytestr_data = void_stack_lim;
+ unsigned char const *pc = bytestr_data;
+ ptrdiff_t count = SPECPDL_INDEX ();
- if (INTEGERP (args_template))
+ if (!NILP (args_template))
{
+ eassert (INTEGERP (args_template));
ptrdiff_t at = XINT (args_template);
bool rest = (at & 128) != 0;
int mandatory = at & 127;
ptrdiff_t nonrest = at >> 8;
- eassert (mandatory <= nonrest);
- if (nargs <= nonrest)
- {
- ptrdiff_t i;
- for (i = 0 ; i < nargs; i++, args++)
- PUSH (*args);
- if (nargs < mandatory)
- /* Too few arguments. */
- Fsignal (Qwrong_number_of_arguments,
- list2 (Fcons (make_number (mandatory),
- rest ? Qand_rest : make_number (nonrest)),
- make_number (nargs)));
- else
- {
- for (; i < nonrest; i++)
- PUSH (Qnil);
- if (rest)
- PUSH (Qnil);
- }
- }
- else if (rest)
- {
- ptrdiff_t i;
- for (i = 0 ; i < nonrest; i++, args++)
- PUSH (*args);
- PUSH (Flist (nargs - nonrest, args));
- }
- else
- /* Too many arguments. */
+ ptrdiff_t maxargs = rest ? PTRDIFF_MAX : nonrest;
+ if (! (mandatory <= nargs && nargs <= maxargs))
Fsignal (Qwrong_number_of_arguments,
list2 (Fcons (make_number (mandatory), make_number (nonrest)),
make_number (nargs)));
- }
- else if (! NILP (args_template))
- /* We should push some arguments on the stack. */
- {
- error ("Unknown args template!");
+ ptrdiff_t pushedargs = min (nonrest, nargs);
+ for (ptrdiff_t i = 0; i < pushedargs; i++, args++)
+ PUSH (*args);
+ if (nonrest < nargs)
+ PUSH (Flist (nargs - nonrest, args));
+ else
+ for (ptrdiff_t i = nargs - rest; i < nonrest; i++)
+ PUSH (Qnil);
}
- while (1)
+ while (true)
{
-#ifdef BYTE_CODE_SAFE
- if (top > stacke)
- emacs_abort ();
- else if (top < stack.bottom - 1)
+ int op;
+ enum handlertype type;
+
+ if (BYTE_CODE_SAFE && ! (stack_base <= top && top < stack_lim))
emacs_abort ();
-#endif
#ifdef BYTE_CODE_METER
- prev_op = this_op;
+ int prev_op = this_op;
this_op = op = FETCH;
METER_CODE (prev_op, op);
-#else
-#ifndef BYTE_CODE_THREADED
+#elif !defined BYTE_CODE_THREADED
op = FETCH;
#endif
-#endif
/* The interpreter can be compiled one of two ways: as an
ordinary switch-based interpreter, or as a threaded
@@ -637,7 +450,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__
@@ -656,7 +469,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
@@ -675,7 +488,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
CASE (Bvarref3):
CASE (Bvarref4):
CASE (Bvarref5):
- op = op - Bvarref;
+ op -= Bvarref;
goto varref;
/* This seems to be the most frequently executed byte-code
@@ -684,92 +497,51 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
op = FETCH;
varref:
{
- Lisp_Object v1, v2;
-
- v1 = vectorp[op];
- if (SYMBOLP (v1))
- {
- if (XSYMBOL (v1)->redirect != SYMBOL_PLAINVAL
- || (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 ();
- }
+ Lisp_Object v1 = vectorp[op], v2;
+ if (!SYMBOLP (v1)
+ || XSYMBOL (v1)->redirect != SYMBOL_PLAINVAL
+ || (v2 = SYMBOL_VAL (XSYMBOL (v1)), EQ (v2, Qunbound)))
+ v2 = Fsymbol_value (v1);
PUSH (v2);
NEXT;
}
CASE (Bgotoifnil):
{
- Lisp_Object v1;
- MAYBE_GC ();
+ Lisp_Object v1 = POP;
op = FETCH2;
- v1 = POP;
if (NILP (v1))
- {
- BYTE_CODE_QUIT;
- CHECK_RANGE (op);
- stack.pc = stack.byte_string_start + op;
- }
+ goto op_branch;
NEXT;
}
CASE (Bcar):
- {
- Lisp_Object v1;
- v1 = TOP;
- if (CONSP (v1))
- TOP = XCAR (v1);
- else if (NILP (v1))
- TOP = Qnil;
- else
- {
- BEFORE_POTENTIAL_GC ();
- wrong_type_argument (Qlistp, v1);
- }
- NEXT;
- }
+ if (CONSP (TOP))
+ TOP = XCAR (TOP);
+ else if (!NILP (TOP))
+ wrong_type_argument (Qlistp, TOP);
+ NEXT;
CASE (Beq):
{
- Lisp_Object v1;
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = EQ (v1, TOP) ? Qt : Qnil;
NEXT;
}
CASE (Bmemq):
{
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = Fmemq (TOP, v1);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Bcdr):
{
- Lisp_Object v1;
- v1 = TOP;
- if (CONSP (v1))
- TOP = XCDR (v1);
- else if (NILP (v1))
- TOP = Qnil;
- else
- {
- BEFORE_POTENTIAL_GC ();
- wrong_type_argument (Qlistp, v1);
- }
+ if (CONSP (TOP))
+ TOP = XCDR (TOP);
+ else if (!NILP (TOP))
+ wrong_type_argument (Qlistp, TOP);
NEXT;
}
@@ -790,31 +562,23 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
op = FETCH;
varset:
{
- Lisp_Object sym, val;
-
- sym = vectorp[op];
- val = TOP;
+ Lisp_Object sym = vectorp[op];
+ Lisp_Object val = POP;
/* Inline the most common case. */
if (SYMBOLP (sym)
&& !EQ (val, Qunbound)
&& !XSYMBOL (sym)->redirect
- && !SYMBOL_CONSTANT_P (sym))
+ && !SYMBOL_TRAPPED_WRITE_P (sym))
SET_SYMBOL_VAL (XSYMBOL (sym), val);
else
- {
- BEFORE_POTENTIAL_GC ();
- set_internal (sym, val, Qnil, 0);
- AFTER_POTENTIAL_GC ();
- }
+ set_internal (sym, val, Qnil, SET_INTERNAL_SET);
}
- (void) POP;
NEXT;
CASE (Bdup):
{
- Lisp_Object v1;
- v1 = TOP;
+ Lisp_Object v1 = TOP;
PUSH (v1);
NEXT;
}
@@ -838,9 +602,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):
@@ -860,15 +622,12 @@ 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))
{
- Lisp_Object v1, v2;
-
- v1 = TOP;
- v2 = Fget (v1, Qbyte_code_meter);
+ Lisp_Object v1 = TOP;
+ Lisp_Object v2 = Fget (v1, Qbyte_code_meter);
if (INTEGERP (v2)
&& XINT (v2) < MOST_POSITIVE_FIXNUM)
{
@@ -878,7 +637,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
}
#endif
TOP = Ffuncall (op + 1, &TOP);
- AFTER_POTENTIAL_GC ();
NEXT;
}
@@ -898,124 +656,85 @@ 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 ();
- BYTE_CODE_QUIT;
- op = FETCH2; /* pc = FETCH2 loses since FETCH2 contains pc++ */
- CHECK_RANGE (op);
- stack.pc = stack.byte_string_start + op;
+ op = FETCH2;
+ op_branch:
+ op -= pc - bytestr_data;
+ op_relative_branch:
+ if (BYTE_CODE_SAFE
+ && ! (bytestr_data - pc <= op
+ && op < bytestr_data + bytestr_length - pc))
+ emacs_abort ();
+ quitcounter += op < 0;
+ if (!quitcounter)
+ {
+ quitcounter = 1;
+ maybe_gc ();
+ QUIT;
+ }
+ pc += op;
NEXT;
CASE (Bgotoifnonnil):
- {
- Lisp_Object v1;
- MAYBE_GC ();
- op = FETCH2;
- v1 = POP;
- if (!NILP (v1))
- {
- BYTE_CODE_QUIT;
- CHECK_RANGE (op);
- stack.pc = stack.byte_string_start + op;
- }
- NEXT;
- }
+ op = FETCH2;
+ if (!NILP (POP))
+ goto op_branch;
+ NEXT;
CASE (Bgotoifnilelsepop):
- MAYBE_GC ();
op = FETCH2;
if (NILP (TOP))
- {
- BYTE_CODE_QUIT;
- CHECK_RANGE (op);
- stack.pc = stack.byte_string_start + op;
- }
- else DISCARD (1);
+ goto op_branch;
+ DISCARD (1);
NEXT;
CASE (Bgotoifnonnilelsepop):
- MAYBE_GC ();
op = FETCH2;
if (!NILP (TOP))
- {
- BYTE_CODE_QUIT;
- CHECK_RANGE (op);
- stack.pc = stack.byte_string_start + op;
- }
- else DISCARD (1);
+ goto op_branch;
+ DISCARD (1);
NEXT;
CASE (BRgoto):
- MAYBE_GC ();
- BYTE_CODE_QUIT;
- stack.pc += (int) *stack.pc - 127;
- NEXT;
+ op = FETCH - 128;
+ goto op_relative_branch;
CASE (BRgotoifnil):
- {
- Lisp_Object v1;
- MAYBE_GC ();
- v1 = POP;
- if (NILP (v1))
- {
- BYTE_CODE_QUIT;
- stack.pc += (int) *stack.pc - 128;
- }
- stack.pc++;
- NEXT;
- }
+ op = FETCH - 128;
+ if (NILP (POP))
+ goto op_relative_branch;
+ NEXT;
CASE (BRgotoifnonnil):
- {
- Lisp_Object v1;
- MAYBE_GC ();
- v1 = POP;
- if (!NILP (v1))
- {
- BYTE_CODE_QUIT;
- stack.pc += (int) *stack.pc - 128;
- }
- stack.pc++;
- NEXT;
- }
+ op = FETCH - 128;
+ if (!NILP (POP))
+ goto op_relative_branch;
+ NEXT;
CASE (BRgotoifnilelsepop):
- MAYBE_GC ();
- op = *stack.pc++;
+ op = FETCH - 128;
if (NILP (TOP))
- {
- BYTE_CODE_QUIT;
- stack.pc += op - 128;
- }
- else DISCARD (1);
+ goto op_relative_branch;
+ DISCARD (1);
NEXT;
CASE (BRgotoifnonnilelsepop):
- MAYBE_GC ();
- op = *stack.pc++;
+ op = FETCH - 128;
if (!NILP (TOP))
- {
- BYTE_CODE_QUIT;
- stack.pc += op - 128;
- }
- else DISCARD (1);
+ goto op_relative_branch;
+ DISCARD (1);
NEXT;
CASE (Breturn):
- result = POP;
goto exit;
CASE (Bdiscard):
@@ -1041,10 +760,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;
}
@@ -1055,11 +772,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;
+ Lisp_Object v1 = POP;
TOP = internal_catch (TOP, eval_sub, v1);
- AFTER_POTENTIAL_GC ();
NEXT;
}
@@ -1070,93 +784,69 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
type = CONDITION_CASE;
pushhandler:
{
- Lisp_Object tag = POP;
- int dest = FETCH2;
-
- struct handler *c = push_handler (tag, type);
- c->bytecode_dest = dest;
+ struct handler *c = push_handler (POP, type);
+ c->bytecode_dest = FETCH2;
c->bytecode_top = top;
if (sys_setjmp (c->jmp))
{
struct handler *c = handlerlist;
- int dest;
top = c->bytecode_top;
- dest = c->bytecode_dest;
+ op = c->bytecode_dest;
handlerlist = c->next;
PUSH (c->val);
- CHECK_RANGE (dest);
- /* Might have been re-set by longjmp! */
- stack.byte_string_start = SDATA (stack.byte_string);
- stack.pc = stack.byte_string_start + dest;
+ goto op_branch;
}
NEXT;
}
CASE (Bpophandler): /* New in 24.4. */
- {
- handlerlist = handlerlist->next;
- NEXT;
- }
+ handlerlist = handlerlist->next;
+ NEXT;
CASE (Bunwind_protect): /* FIXME: avoid closure for lexbind. */
{
Lisp_Object handler = POP;
/* Support for a function here is new in 24.4. */
- record_unwind_protect (NILP (Ffunctionp (handler))
- ? unwind_body : bcall0,
+ record_unwind_protect (FUNCTIONP (handler) ? bcall0 : prog_ignore,
handler);
NEXT;
}
CASE (Bcondition_case): /* Obsolete since 24.4. */
{
- Lisp_Object handlers, body;
- handlers = POP;
- body = POP;
- BEFORE_POTENTIAL_GC ();
+ Lisp_Object handlers = POP, body = POP;
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;
+ Lisp_Object v1 = POP;
temp_output_buffer_show (TOP);
TOP = v1;
/* pop binding of standard-output */
unbind_to (SPECPDL_INDEX () - 1, Qnil);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Bnth):
{
- Lisp_Object v1, v2;
- EMACS_INT n;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
- v2 = TOP;
- CHECK_NUMBER (v2);
- n = XINT (v2);
- immediate_quit = 1;
- while (--n >= 0 && CONSP (v1))
- v1 = XCDR (v1);
- immediate_quit = 0;
- TOP = CAR (v1);
- AFTER_POTENTIAL_GC ();
+ Lisp_Object v2 = POP, v1 = TOP;
+ CHECK_NUMBER (v1);
+ EMACS_INT n = XINT (v1);
+ immediate_quit = true;
+ while (--n >= 0 && CONSP (v2))
+ v2 = XCDR (v2);
+ immediate_quit = false;
+ TOP = CAR (v2);
NEXT;
}
@@ -1182,8 +872,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
CASE (Bcons):
{
- Lisp_Object v1;
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = Fcons (TOP, v1);
NEXT;
}
@@ -1194,8 +883,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
CASE (Blist2):
{
- Lisp_Object v1;
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = list2 (TOP, v1);
NEXT;
}
@@ -1217,305 +905,191 @@ 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;
+ Lisp_Object v1 = POP;
TOP = Faref (TOP, v1);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Baset):
{
- Lisp_Object v1, v2;
- BEFORE_POTENTIAL_GC ();
- v2 = POP; v1 = POP;
+ Lisp_Object 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;
+ Lisp_Object v1 = POP;
TOP = Fset (TOP, v1);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Bfset):
{
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = Ffset (TOP, v1);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Bget):
{
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = Fget (TOP, v1);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Bsubstring):
{
- Lisp_Object v1, v2;
- BEFORE_POTENTIAL_GC ();
- v2 = POP; v1 = POP;
+ Lisp_Object 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):
- {
- Lisp_Object v1;
- v1 = TOP;
- if (INTEGERP (v1))
- {
- XSETINT (v1, XINT (v1) - 1);
- TOP = v1;
- }
- else
- {
- BEFORE_POTENTIAL_GC ();
- TOP = Fsub1 (v1);
- AFTER_POTENTIAL_GC ();
- }
- NEXT;
- }
+ TOP = INTEGERP (TOP) ? make_number (XINT (TOP) - 1) : Fsub1 (TOP);
+ NEXT;
CASE (Badd1):
- {
- Lisp_Object v1;
- v1 = TOP;
- if (INTEGERP (v1))
- {
- XSETINT (v1, XINT (v1) + 1);
- TOP = v1;
- }
- else
- {
- BEFORE_POTENTIAL_GC ();
- TOP = Fadd1 (v1);
- AFTER_POTENTIAL_GC ();
- }
- NEXT;
- }
+ TOP = INTEGERP (TOP) ? make_number (XINT (TOP) + 1) : Fadd1 (TOP);
+ NEXT;
CASE (Beqlsign):
{
- Lisp_Object v1, v2;
- BEFORE_POTENTIAL_GC ();
- v2 = POP; v1 = TOP;
+ Lisp_Object v2 = POP, v1 = TOP;
CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (v1);
CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (v2);
- AFTER_POTENTIAL_GC ();
+ bool equal;
if (FLOATP (v1) || FLOATP (v2))
{
- double f1, f2;
-
- f1 = (FLOATP (v1) ? XFLOAT_DATA (v1) : XINT (v1));
- f2 = (FLOATP (v2) ? XFLOAT_DATA (v2) : XINT (v2));
- TOP = (f1 == f2 ? Qt : Qnil);
+ double f1 = FLOATP (v1) ? XFLOAT_DATA (v1) : XINT (v1);
+ double f2 = FLOATP (v2) ? XFLOAT_DATA (v2) : XINT (v2);
+ equal = f1 == f2;
}
else
- TOP = (XINT (v1) == XINT (v2) ? Qt : Qnil);
+ equal = XINT (v1) == XINT (v2);
+ TOP = equal ? Qt : Qnil;
NEXT;
}
CASE (Bgtr):
{
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = arithcompare (TOP, v1, ARITH_GRTR);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Blss):
{
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = arithcompare (TOP, v1, ARITH_LESS);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Bleq):
{
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = arithcompare (TOP, v1, ARITH_LESS_OR_EQUAL);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Bgeq):
{
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object 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):
- {
- Lisp_Object v1;
- v1 = TOP;
- if (INTEGERP (v1))
- {
- XSETINT (v1, - XINT (v1));
- TOP = v1;
- }
- else
- {
- BEFORE_POTENTIAL_GC ();
- TOP = Fminus (1, &TOP);
- AFTER_POTENTIAL_GC ();
- }
- NEXT;
- }
+ TOP = INTEGERP (TOP) ? make_number (- XINT (TOP)) : Fminus (1, &TOP);
+ 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;
+ Lisp_Object v1 = POP;
TOP = Frem (TOP, v1);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Bpoint):
- {
- Lisp_Object v1;
- XSETFASTINT (v1, PT);
- PUSH (v1);
- NEXT;
- }
+ PUSH (make_natnum (PT));
+ NEXT;
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):
@@ -1527,53 +1101,27 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
}
CASE (Bpoint_min):
- {
- Lisp_Object v1;
- XSETFASTINT (v1, BEGV);
- PUSH (v1);
- NEXT;
- }
+ PUSH (make_natnum (BEGV));
+ NEXT;
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;
- }
+ PUSH (Ffollowing_char ());
+ NEXT;
CASE (Bpreceding_char):
- {
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = Fprevious_char ();
- AFTER_POTENTIAL_GC ();
- PUSH (v1);
- NEXT;
- }
+ PUSH (Fprevious_char ());
+ NEXT;
CASE (Bcurrent_column):
- {
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- XSETFASTINT (v1, current_column ());
- AFTER_POTENTIAL_GC ();
- PUSH (v1);
- NEXT;
- }
+ PUSH (make_natnum (current_column ()));
+ NEXT;
CASE (Bindent_to):
- BEFORE_POTENTIAL_GC ();
TOP = Findent_to (TOP, Qnil);
- AFTER_POTENTIAL_GC ();
NEXT;
CASE (Beolp):
@@ -1597,63 +1145,43 @@ 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;
+ Lisp_Object v1 = POP;
TOP = Fskip_chars_forward (TOP, v1);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Bskip_chars_backward):
{
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object 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);
+ int c = XFASTINT (TOP);
if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
MAKE_CHAR_MULTIBYTE (c);
XSETFASTINT (TOP, syntax_code_spec[SYNTAX (c)]);
@@ -1662,239 +1190,169 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
CASE (Bbuffer_substring):
{
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = Fbuffer_substring (TOP, v1);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Bdelete_region):
{
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = Fdelete_region (TOP, v1);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Bnarrow_to_region):
{
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object 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 ();
+ Lisp_Object v2 = POP, v1 = POP;
+ TOP = Fset_marker (TOP, v1, v2);
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;
+ NEXT;
- CASE (Bstringeqlsign):
+ CASE (Bstringeqlsign):
{
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = Fstring_equal (TOP, v1);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Bstringlss):
{
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = Fstring_lessp (TOP, v1);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Bequal):
{
- Lisp_Object v1;
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = Fequal (TOP, v1);
NEXT;
}
CASE (Bnthcdr):
{
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = Fnthcdr (TOP, v1);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Belt):
{
- Lisp_Object v1, v2;
if (CONSP (TOP))
{
/* Exchange args and then do nth. */
- EMACS_INT n;
- BEFORE_POTENTIAL_GC ();
- v2 = POP;
- v1 = TOP;
+ Lisp_Object v2 = POP, v1 = TOP;
CHECK_NUMBER (v2);
- AFTER_POTENTIAL_GC ();
- n = XINT (v2);
- immediate_quit = 1;
+ EMACS_INT n = XINT (v2);
+ immediate_quit = true;
while (--n >= 0 && CONSP (v1))
v1 = XCDR (v1);
- immediate_quit = 0;
+ immediate_quit = false;
TOP = CAR (v1);
}
else
{
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = Felt (TOP, v1);
- AFTER_POTENTIAL_GC ();
}
NEXT;
}
CASE (Bmember):
{
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = Fmember (TOP, v1);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Bassq):
{
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object 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;
+ Lisp_Object v1 = POP;
TOP = Fsetcar (TOP, v1);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Bsetcdr):
{
- Lisp_Object v1;
- BEFORE_POTENTIAL_GC ();
- v1 = POP;
+ Lisp_Object v1 = POP;
TOP = Fsetcdr (TOP, v1);
- AFTER_POTENTIAL_GC ();
NEXT;
}
CASE (Bcar_safe):
- {
- Lisp_Object v1;
- v1 = TOP;
- TOP = CAR_SAFE (v1);
- NEXT;
- }
+ TOP = CAR_SAFE (TOP);
+ NEXT;
CASE (Bcdr_safe):
- {
- Lisp_Object v1;
- v1 = TOP;
- TOP = CDR_SAFE (v1);
- NEXT;
- }
+ TOP = CDR_SAFE (TOP);
+ NEXT;
CASE (Bnconc):
- BEFORE_POTENTIAL_GC ();
DISCARD (1);
TOP = Fnconc (2, &TOP);
- AFTER_POTENTIAL_GC ();
NEXT;
CASE (Bnumberp):
- TOP = (NUMBERP (TOP) ? Qt : Qnil);
+ TOP = NUMBERP (TOP) ? Qt : Qnil;
NEXT;
CASE (Bintegerp):
TOP = INTEGERP (TOP) ? Qt : Qnil;
NEXT;
-#ifdef BYTE_CODE_SAFE
+#if BYTE_CODE_SAFE
/* These are intentionally written using 'case' syntax,
because they are incompatible with the threaded
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
@@ -1905,7 +1363,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
call3 (Qerror,
build_string ("Invalid byte opcode: op=%s, ptr=%d"),
make_number (op),
- make_number ((stack.pc - 1) - stack.byte_string_start));
+ make_number (pc - 1 - bytestr_data));
/* Handy byte-codes for lexical binding. */
CASE (Bstack_ref1):
@@ -1914,32 +1372,32 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
CASE (Bstack_ref4):
CASE (Bstack_ref5):
{
- Lisp_Object *ptr = top - (op - Bstack_ref);
- PUSH (*ptr);
+ Lisp_Object v1 = top[Bstack_ref - op];
+ PUSH (v1);
NEXT;
}
CASE (Bstack_ref6):
{
- Lisp_Object *ptr = top - (FETCH);
- PUSH (*ptr);
+ Lisp_Object v1 = top[- FETCH];
+ PUSH (v1);
NEXT;
}
CASE (Bstack_ref7):
{
- Lisp_Object *ptr = top - (FETCH2);
- PUSH (*ptr);
+ Lisp_Object v1 = top[- FETCH2];
+ PUSH (v1);
NEXT;
}
CASE (Bstack_set):
/* stack-set-0 = discard; stack-set-1 = discard-1-preserve-tos. */
{
- Lisp_Object *ptr = top - (FETCH);
+ Lisp_Object *ptr = top - FETCH;
*ptr = POP;
NEXT;
}
CASE (Bstack_set2):
{
- Lisp_Object *ptr = top - (FETCH2);
+ Lisp_Object *ptr = top - FETCH2;
*ptr = POP;
NEXT;
}
@@ -1955,27 +1413,16 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
CASE_DEFAULT
CASE (Bconstant):
-#ifdef BYTE_CODE_SAFE
- if (op < Bconstant)
- {
- emacs_abort ();
- }
- if ((op -= Bconstant) >= const_length)
- {
- emacs_abort ();
- }
- PUSH (vectorp[op]);
-#else
+ if (BYTE_CODE_SAFE
+ && ! (Bconstant <= op && op < Bconstant + const_length))
+ emacs_abort ();
PUSH (vectorp[op - Bconstant]);
-#endif
NEXT;
}
}
exit:
- byte_stack_list = byte_stack_list->next;
-
/* Binds and unbinds are supposed to be compiled balanced. */
if (SPECPDL_INDEX () != count)
{
@@ -1984,9 +1431,25 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
error ("binding stack not balanced (serious byte compiler bug)");
}
+ Lisp_Object result = TOP;
+ SAFE_FREE ();
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)
{
@@ -2008,7 +1471,7 @@ The variable byte-code-meter indicates how often each byte opcode is used.
If a symbol has a property named `byte-code-meter' whose value is an
integer, it is incremented each time that symbol's function is called. */);
- byte_metering_on = 0;
+ byte_metering_on = false;
Vbyte_code_meter = Fmake_vector (make_number (256), make_number (0));
DEFSYM (Qbyte_code_meter, "byte-code-meter");
{