aboutsummaryrefslogtreecommitdiffstats
path: root/src/bytecode.c
diff options
context:
space:
mode:
authorStefan Monnier2013-10-03 00:58:56 -0400
committerStefan Monnier2013-10-03 00:58:56 -0400
commitadf2aa61404305e58e71cde0193bb650aff2c4b3 (patch)
treed6e6b4e5ab3b144a94daed2232cab798aadeb20a /src/bytecode.c
parent328a8179fec33f5a75e2cfe22e43f4ec0df770b7 (diff)
downloademacs-adf2aa61404305e58e71cde0193bb650aff2c4b3.tar.gz
emacs-adf2aa61404305e58e71cde0193bb650aff2c4b3.zip
Introduce new bytecodes for efficient catch/condition-case in lexbind.
* lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Optimize under `condition-case' and `catch' if byte-compile--use-old-handlers is nil. (disassemble-offset): Handle new bytecodes. * lisp/emacs-lisp/bytecomp.el (byte-pushcatch, byte-pushconditioncase) (byte-pophandler): New byte codes. (byte-goto-ops): Adjust accordingly. (byte-compile--use-old-handlers): New var. (byte-compile-catch): Use new byte codes depending on byte-compile--use-old-handlers. (byte-compile-condition-case--old): Rename from byte-compile-condition-case. (byte-compile-condition-case--new): New function. (byte-compile-condition-case): New function that dispatches depending on byte-compile--use-old-handlers. (byte-compile-unwind-protect): Pass a function to byte-unwind-protect when we can. * lisp/emacs-lisp/cconv.el (cconv-convert, cconv-analyse-form): Adjust for the new compilation scheme using the new byte-codes. * src/alloc.c (Fgarbage_collect): Merge scans of handlerlist and catchlist, and make them unconditional now that they're heap-allocated. * src/bytecode.c (BYTE_CODES): Add Bpushcatch, Bpushconditioncase and Bpophandler. (bcall0): New function. (exec_byte_code): Add corresponding cases. Improve error message when encountering an invalid byte-code. Let Bunwind_protect accept a function (rather than a list of expressions) as argument. * src/eval.c (catchlist): Remove (merge with handlerlist). (handlerlist, lisp_eval_depth): Not static any more. (internal_catch, internal_condition_case, internal_condition_case_1) (internal_condition_case_2, internal_condition_case_n): Use PUSH_HANDLER. (unwind_to_catch, Fthrow, Fsignal): Adjust to merged handlerlist/catchlist. (internal_lisp_condition_case): Use PUSH_HANDLER. Adjust to new handlerlist which can only handle a single condition-case handler at a time. (find_handler_clause): Simplify since we only a single branch here any more. * src/lisp.h (struct handler): Merge struct handler and struct catchtag. (PUSH_HANDLER): New macro. (catchlist): Remove. (handlerlist): Always declare.
Diffstat (limited to 'src/bytecode.c')
-rw-r--r--src/bytecode.c79
1 files changed, 69 insertions, 10 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index 23e50826633..f7ccd35cbba 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -141,6 +141,10 @@ DEFINE (Bunbind5, 055) \
141DEFINE (Bunbind6, 056) \ 141DEFINE (Bunbind6, 056) \
142DEFINE (Bunbind7, 057) \ 142DEFINE (Bunbind7, 057) \
143 \ 143 \
144DEFINE (Bpophandler, 060) \
145DEFINE (Bpushconditioncase, 061) \
146DEFINE (Bpushcatch, 062) \
147 \
144DEFINE (Bnth, 070) \ 148DEFINE (Bnth, 070) \
145DEFINE (Bsymbolp, 071) \ 149DEFINE (Bsymbolp, 071) \
146DEFINE (Bconsp, 072) \ 150DEFINE (Bconsp, 072) \
@@ -478,6 +482,12 @@ If the third argument is incorrect, Emacs may crash. */)
478 return exec_byte_code (bytestr, vector, maxdepth, Qnil, 0, NULL); 482 return exec_byte_code (bytestr, vector, maxdepth, Qnil, 0, NULL);
479} 483}
480 484
485static void
486bcall0 (Lisp_Object f)
487{
488 Ffuncall (1, &f);
489}
490
481/* Execute the byte-code in BYTESTR. VECTOR is the constant vector, and 491/* Execute the byte-code in BYTESTR. VECTOR is the constant vector, and
482 MAXDEPTH is the maximum stack depth used (if MAXDEPTH is incorrect, 492 MAXDEPTH is the maximum stack depth used (if MAXDEPTH is incorrect,
483 emacs may crash!). If ARGS_TEMPLATE is non-nil, it should be a lisp 493 emacs may crash!). If ARGS_TEMPLATE is non-nil, it should be a lisp
@@ -506,6 +516,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
506 struct byte_stack stack; 516 struct byte_stack stack;
507 Lisp_Object *top; 517 Lisp_Object *top;
508 Lisp_Object result; 518 Lisp_Object result;
519 enum handlertype type;
509 520
510#if 0 /* CHECK_FRAME_FONT */ 521#if 0 /* CHECK_FRAME_FONT */
511 { 522 {
@@ -1078,7 +1089,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1078 save_restriction_save ()); 1089 save_restriction_save ());
1079 NEXT; 1090 NEXT;
1080 1091
1081 CASE (Bcatch): /* FIXME: ill-suited for lexbind. */ 1092 CASE (Bcatch): /* Obsolete since 24.4. */
1082 { 1093 {
1083 Lisp_Object v1; 1094 Lisp_Object v1;
1084 BEFORE_POTENTIAL_GC (); 1095 BEFORE_POTENTIAL_GC ();
@@ -1088,11 +1099,56 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1088 NEXT; 1099 NEXT;
1089 } 1100 }
1090 1101
1102 CASE (Bpushcatch): /* New in 24.4. */
1103 type = CATCHER;
1104 goto pushhandler;
1105 CASE (Bpushconditioncase): /* New in 24.4. */
1106 {
1107 extern EMACS_INT lisp_eval_depth;
1108 extern int poll_suppress_count;
1109 extern int interrupt_input_blocked;
1110 struct handler *c;
1111 Lisp_Object tag;
1112 int dest;
1113
1114 type = CONDITION_CASE;
1115 pushhandler:
1116 tag = POP;
1117 dest = FETCH2;
1118
1119 PUSH_HANDLER (c, tag, type);
1120 c->bytecode_dest = dest;
1121 c->bytecode_top = top;
1122 if (sys_setjmp (c->jmp))
1123 {
1124 struct handler *c = handlerlist;
1125 top = c->bytecode_top;
1126 int dest = c->bytecode_dest;
1127 handlerlist = c->next;
1128 PUSH (c->val);
1129 CHECK_RANGE (dest);
1130 stack.pc = stack.byte_string_start + dest;
1131 }
1132 NEXT;
1133 }
1134
1135 CASE (Bpophandler): /* New in 24.4. */
1136 {
1137 handlerlist = handlerlist->next;
1138 NEXT;
1139 }
1140
1091 CASE (Bunwind_protect): /* FIXME: avoid closure for lexbind. */ 1141 CASE (Bunwind_protect): /* FIXME: avoid closure for lexbind. */
1092 record_unwind_protect (unwind_body, POP); 1142 {
1093 NEXT; 1143 Lisp_Object handler = POP;
1144 /* Support for a function here is new in 24.4. */
1145 record_unwind_protect (NILP (Ffunctionp (handler))
1146 ? unwind_body : bcall0,
1147 handler);
1148 NEXT;
1149 }
1094 1150
1095 CASE (Bcondition_case): /* FIXME: ill-suited for lexbind. */ 1151 CASE (Bcondition_case): /* Obsolete since 24.4. */
1096 { 1152 {
1097 Lisp_Object handlers, body; 1153 Lisp_Object handlers, body;
1098 handlers = POP; 1154 handlers = POP;
@@ -1884,7 +1940,10 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1884 /* Actually this is Bstack_ref with offset 0, but we use Bdup 1940 /* Actually this is Bstack_ref with offset 0, but we use Bdup
1885 for that instead. */ 1941 for that instead. */
1886 /* CASE (Bstack_ref): */ 1942 /* CASE (Bstack_ref): */
1887 error ("Invalid byte opcode"); 1943 call3 (intern ("error"),
1944 build_string ("Invalid byte opcode: op=%s, ptr=%d"),
1945 make_number (op),
1946 make_number ((stack.pc - 1) - stack.byte_string_start));
1888 1947
1889 /* Handy byte-codes for lexical binding. */ 1948 /* Handy byte-codes for lexical binding. */
1890 CASE (Bstack_ref1): 1949 CASE (Bstack_ref1):
@@ -1957,11 +2016,11 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1957 2016
1958 /* Binds and unbinds are supposed to be compiled balanced. */ 2017 /* Binds and unbinds are supposed to be compiled balanced. */
1959 if (SPECPDL_INDEX () != count) 2018 if (SPECPDL_INDEX () != count)
1960#ifdef BYTE_CODE_SAFE 2019 {
1961 error ("binding stack not balanced (serious byte compiler bug)"); 2020 if (SPECPDL_INDEX () > count)
1962#else 2021 unbind_to (count, Qnil);
1963 emacs_abort (); 2022 error ("binding stack not balanced (serious byte compiler bug)");
1964#endif 2023 }
1965 2024
1966 return result; 2025 return result;
1967} 2026}