diff options
| author | Stefan Monnier | 2013-10-03 00:58:56 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2013-10-03 00:58:56 -0400 |
| commit | adf2aa61404305e58e71cde0193bb650aff2c4b3 (patch) | |
| tree | d6e6b4e5ab3b144a94daed2232cab798aadeb20a /src/bytecode.c | |
| parent | 328a8179fec33f5a75e2cfe22e43f4ec0df770b7 (diff) | |
| download | emacs-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.c | 79 |
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) \ | |||
| 141 | DEFINE (Bunbind6, 056) \ | 141 | DEFINE (Bunbind6, 056) \ |
| 142 | DEFINE (Bunbind7, 057) \ | 142 | DEFINE (Bunbind7, 057) \ |
| 143 | \ | 143 | \ |
| 144 | DEFINE (Bpophandler, 060) \ | ||
| 145 | DEFINE (Bpushconditioncase, 061) \ | ||
| 146 | DEFINE (Bpushcatch, 062) \ | ||
| 147 | \ | ||
| 144 | DEFINE (Bnth, 070) \ | 148 | DEFINE (Bnth, 070) \ |
| 145 | DEFINE (Bsymbolp, 071) \ | 149 | DEFINE (Bsymbolp, 071) \ |
| 146 | DEFINE (Bconsp, 072) \ | 150 | DEFINE (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 | ||
| 485 | static void | ||
| 486 | bcall0 (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 | } |