/* Execution of byte code produced by bytecomp.el.
- Copyright (C) 1985-1988, 1993, 2000-2013 Free Software Foundation,
+ Copyright (C) 1985-1988, 1993, 2000-2014 Free Software Foundation,
Inc.
This file is part of GNU Emacs.
Bscan_buffer = 0153, /* No longer generated as of v18. */
Bset_mark = 0163, /* this loser is no longer generated as of v18 */
#endif
-
- B__dummy__ = 0 /* Pacify C89. */
};
-
-/* Whether to maintain a `top' and `bottom' field in the stack frame. */
-#define BYTE_MAINTAIN_TOP (BYTE_CODE_SAFE || BYTE_MARK_STACK)
\f
/* Structure describing a value stack used during byte-code execution
in Fbyte_code. */
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. */
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;
};
-
-/* 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 removed the entry again when it is
- done. Signaling an error truncates the list analogous to
- gcprolist. */
-
-struct byte_stack *byte_stack_list;
-
-\f
-/* 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. */
-
-void
-unmark_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;
- }
- }
-}
-
\f
/* 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
/* Fetch two bytes from the bytecode stream and make a 16-bit number
out of them. */
/* 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. */
{
ptrdiff_t count = SPECPDL_INDEX ();
#ifdef BYTE_CODE_METER
- int this_op = 0;
+ int volatile this_op = 0;
int prev_op;
#endif
int op;
#ifdef BYTE_CODE_SAFE
bytestr_length = SBYTES (bytestr);
#endif
- vectorp = XVECTOR (vector)->u.contents;
+ 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);
PUSH_HANDLER (c, tag, type);
c->bytecode_dest = dest;
c->bytecode_top = top;
+
if (sys_setjmp (c->jmp))
{
struct handler *c = handlerlist;
+ int dest;
top = c->bytecode_top;
- int dest = c->bytecode_dest;
+ dest = 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;
}
+
NEXT;
}
exit:
- byte_stack_list = byte_stack_list->next;
-
/* Binds and unbinds are supposed to be compiled balanced. */
if (SPECPDL_INDEX () != count)
{
void
syms_of_bytecode (void)
{
- defsubr (&Sbyte_code);
+#include "bytecode.x"
#ifdef BYTE_CODE_METER