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 (BYTE_CODE_SAFE) && !defined (BYTE_CODE_METER)
+#if (defined __GNUC__ && !defined __STRICT_ANSI__ \
+ && !defined BYTE_CODE_SAFE && !defined BYTE_CODE_METER)
#define BYTE_CODE_THREADED
#endif
DEFINE (Bunbind6, 056) \
DEFINE (Bunbind7, 057) \
\
+DEFINE (Bpophandler, 060) \
+DEFINE (Bpushconditioncase, 061) \
+DEFINE (Bpushcatch, 062) \
+ \
DEFINE (Bnth, 070) \
DEFINE (Bsymbolp, 071) \
DEFINE (Bconsp, 072) \
#ifdef BYTE_CODE_SAFE
Bscan_buffer = 0153, /* No longer generated as of v18. */
- Bset_mark = 0163 /* this loser is 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. */
/* 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
+ processing byte-code, and it removes the entry again when it is
done. Signaling an error truncates the list analogous to
gcprolist. */
return exec_byte_code (bytestr, vector, maxdepth, Qnil, 0, NULL);
}
+static void
+bcall0 (Lisp_Object f)
+{
+ Ffuncall (1, &f);
+}
+
/* Execute the byte-code in BYTESTR. VECTOR is the constant vector, and
MAXDEPTH is the maximum stack depth used (if MAXDEPTH is incorrect,
emacs may crash!). If ARGS_TEMPLATE is non-nil, it should be a lisp
Lisp_Object args_template, ptrdiff_t nargs, Lisp_Object *args)
{
ptrdiff_t count = SPECPDL_INDEX ();
+ ptrdiff_t volatile count_volatile;
#ifdef BYTE_CODE_METER
- int this_op = 0;
+ int volatile this_op = 0;
int prev_op;
#endif
int op;
/* Lisp_Object v1, v2; */
Lisp_Object *vectorp;
+ Lisp_Object *volatile vectorp_volatile;
#ifdef BYTE_CODE_SAFE
- ptrdiff_t const_length;
- Lisp_Object *stacke;
- ptrdiff_t bytestr_length;
+ ptrdiff_t volatile const_length;
+ Lisp_Object *volatile stacke;
+ ptrdiff_t volatile bytestr_length;
#endif
struct byte_stack stack;
+ struct byte_stack volatile stack_volatile;
Lisp_Object *top;
Lisp_Object result;
+ enum handlertype type;
#if 0 /* CHECK_FRAME_FONT */
{
if (nargs < mandatory)
/* Too few arguments. */
Fsignal (Qwrong_number_of_arguments,
- Fcons (Fcons (make_number (mandatory),
+ list2 (Fcons (make_number (mandatory),
rest ? Qand_rest : make_number (nonrest)),
- Fcons (make_number (nargs), Qnil)));
+ make_number (nargs)));
else
{
for (; i < nonrest; i++)
else
/* Too many arguments. */
Fsignal (Qwrong_number_of_arguments,
- Fcons (Fcons (make_number (mandatory),
- make_number (nonrest)),
- Fcons (make_number (nargs), Qnil)));
+ list2 (Fcons (make_number (mandatory), make_number (nonrest)),
+ make_number (nargs)));
}
else if (! NILP (args_template))
/* We should push some arguments on the stack. */
the table clearer. */
#define LABEL(OP) [OP] = &&insn_ ## OP
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Woverride-init"
+#elif defined __clang__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Winitializer-overrides"
#endif
/* This is the dispatch table for the threaded interpreter. */
#undef DEFINE
};
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) || defined __clang__
# pragma GCC diagnostic pop
#endif
CASE (Bsave_window_excursion): /* Obsolete since 24.1. */
{
- register ptrdiff_t count1 = SPECPDL_INDEX ();
- record_unwind_protect (Fset_window_configuration,
+ ptrdiff_t count1 = SPECPDL_INDEX ();
+ record_unwind_protect (restore_window_configuration,
Fcurrent_window_configuration (Qnil));
BEFORE_POTENTIAL_GC ();
TOP = Fprogn (TOP);
save_restriction_save ());
NEXT;
- CASE (Bcatch): /* FIXME: ill-suited for lexbind. */
+ CASE (Bcatch): /* Obsolete since 24.4. */
{
Lisp_Object v1;
BEFORE_POTENTIAL_GC ();
NEXT;
}
+ CASE (Bpushcatch): /* New in 24.4. */
+ type = CATCHER;
+ goto pushhandler;
+ CASE (Bpushconditioncase): /* New in 24.4. */
+ {
+ extern EMACS_INT lisp_eval_depth;
+ extern int poll_suppress_count;
+ extern int interrupt_input_blocked;
+ struct handler *c;
+ Lisp_Object tag;
+ int dest;
+
+ type = CONDITION_CASE;
+ pushhandler:
+ tag = POP;
+ dest = FETCH2;
+
+ PUSH_HANDLER (c, tag, type);
+ c->bytecode_dest = dest;
+ c->bytecode_top = top;
+ count_volatile = count;
+ stack_volatile = stack;
+ vectorp_volatile = vectorp;
+
+ if (sys_setjmp (c->jmp))
+ {
+ struct handler *c = handlerlist;
+ int dest;
+ top = c->bytecode_top;
+ dest = c->bytecode_dest;
+ handlerlist = c->next;
+ PUSH (c->val);
+ CHECK_RANGE (dest);
+ stack = stack_volatile;
+ stack.pc = stack.byte_string_start + dest;
+ }
+
+ count = count_volatile;
+ vectorp = vectorp_volatile;
+ NEXT;
+ }
+
+ CASE (Bpophandler): /* New in 24.4. */
+ {
+ handlerlist = handlerlist->next;
+ NEXT;
+ }
+
CASE (Bunwind_protect): /* FIXME: avoid closure for lexbind. */
- record_unwind_protect (Fprogn, POP);
- NEXT;
+ {
+ Lisp_Object handler = POP;
+ /* Support for a function here is new in 24.4. */
+ record_unwind_protect (NILP (Ffunctionp (handler))
+ ? unwind_body : bcall0,
+ handler);
+ NEXT;
+ }
- CASE (Bcondition_case): /* FIXME: ill-suited for lexbind. */
+ CASE (Bcondition_case): /* Obsolete since 24.4. */
{
Lisp_Object handlers, body;
handlers = POP;
}
CASE (Blist1):
- TOP = Fcons (TOP, Qnil);
+ TOP = list1 (TOP);
NEXT;
CASE (Blist2):
{
Lisp_Object v1;
v1 = POP;
- TOP = Fcons (TOP, Fcons (v1, Qnil));
+ TOP = list2 (TOP, v1);
NEXT;
}
Lisp_Object v1;
BEFORE_POTENTIAL_GC ();
v1 = POP;
- TOP = Fgtr (TOP, v1);
+ TOP = arithcompare (TOP, v1, ARITH_GRTR);
AFTER_POTENTIAL_GC ();
NEXT;
}
Lisp_Object v1;
BEFORE_POTENTIAL_GC ();
v1 = POP;
- TOP = Flss (TOP, v1);
+ TOP = arithcompare (TOP, v1, ARITH_LESS);
AFTER_POTENTIAL_GC ();
NEXT;
}
Lisp_Object v1;
BEFORE_POTENTIAL_GC ();
v1 = POP;
- TOP = Fleq (TOP, v1);
+ TOP = arithcompare (TOP, v1, ARITH_LESS_OR_EQUAL);
AFTER_POTENTIAL_GC ();
NEXT;
}
Lisp_Object v1;
BEFORE_POTENTIAL_GC ();
v1 = POP;
- TOP = Fgeq (TOP, v1);
+ TOP = arithcompare (TOP, v1, ARITH_GRTR_OR_EQUAL);
AFTER_POTENTIAL_GC ();
NEXT;
}
c = XFASTINT (TOP);
if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
MAKE_CHAR_MULTIBYTE (c);
- XSETFASTINT (TOP, syntax_code_spec[(int) SYNTAX (c)]);
+ XSETFASTINT (TOP, syntax_code_spec[SYNTAX (c)]);
}
NEXT;
/* Actually this is Bstack_ref with offset 0, but we use Bdup
for that instead. */
/* CASE (Bstack_ref): */
- error ("Invalid byte opcode");
+ call3 (intern ("error"),
+ build_string ("Invalid byte opcode: op=%s, ptr=%d"),
+ make_number (op),
+ make_number ((stack.pc - 1) - stack.byte_string_start));
/* Handy byte-codes for lexical binding. */
CASE (Bstack_ref1):
/* Binds and unbinds are supposed to be compiled balanced. */
if (SPECPDL_INDEX () != count)
-#ifdef BYTE_CODE_SAFE
- error ("binding stack not balanced (serious byte compiler bug)");
-#else
- emacs_abort ();
-#endif
+ {
+ if (SPECPDL_INDEX () > count)
+ unbind_to (count, Qnil);
+ error ("binding stack not balanced (serious byte compiler bug)");
+ }
return result;
}