diff options
| author | Nickolas Lloyd | 2017-02-01 20:28:55 -0500 |
|---|---|---|
| committer | Nickolas Lloyd | 2017-02-01 20:28:55 -0500 |
| commit | 3dcb25deaefb52c9d314c4eddb93a3a815a58ec0 (patch) | |
| tree | 4abdced92049dcfb25576ffe16a708b1d680a1d0 /src/bytecode.c | |
| parent | 3ccffad606386a9344b592cb35bda9c5a1714242 (diff) | |
| parent | f3c77d11af65f3b319b1784b4c3cf08c51aa7997 (diff) | |
| download | emacs-3dcb25deaefb52c9d314c4eddb93a3a815a58ec0.tar.gz emacs-3dcb25deaefb52c9d314c4eddb93a3a815a58ec0.zip | |
Merge branch 'master' into nick.lloyd-bytecode-jit
Diffstat (limited to 'src/bytecode.c')
| -rw-r--r-- | src/bytecode.c | 154 |
1 files changed, 51 insertions, 103 deletions
diff --git a/src/bytecode.c b/src/bytecode.c index 3e64d2f42b6..02a3f700fdd 100644 --- a/src/bytecode.c +++ b/src/bytecode.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Execution of byte code produced by bytecomp.el. | 1 | /* Execution of byte code produced by bytecomp.el. |
| 2 | Copyright (C) 1985-1988, 1993, 2000-2016 Free Software Foundation, | 2 | Copyright (C) 1985-1988, 1993, 2000-2017 Free Software Foundation, |
| 3 | Inc. | 3 | Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| @@ -81,11 +81,8 @@ relocate_byte_stack (struct byte_stack *stack) | |||
| 81 | 81 | ||
| 82 | 82 | ||
| 83 | /* Fetch the next byte from the bytecode stream. */ | 83 | /* Fetch the next byte from the bytecode stream. */ |
| 84 | #ifdef BYTE_CODE_SAFE | 84 | |
| 85 | #define FETCH (eassert (stack.byte_string_start == SDATA (stack.byte_string)), *stack.pc++) | 85 | #define FETCH (*pc++) |
| 86 | #else | ||
| 87 | #define FETCH *stack.pc++ | ||
| 88 | #endif | ||
| 89 | 86 | ||
| 90 | /* Fetch two bytes from the bytecode stream and make a 16-bit number | 87 | /* Fetch two bytes from the bytecode stream and make a 16-bit number |
| 91 | out of them. */ | 88 | out of them. */ |
| @@ -110,29 +107,6 @@ relocate_byte_stack (struct byte_stack *stack) | |||
| 110 | 107 | ||
| 111 | #define TOP (*top) | 108 | #define TOP (*top) |
| 112 | 109 | ||
| 113 | #define CHECK_RANGE(ARG) \ | ||
| 114 | (BYTE_CODE_SAFE && bytestr_length <= (ARG) ? emacs_abort () : (void) 0) | ||
| 115 | |||
| 116 | /* A version of the QUIT macro which makes sure that the stack top is | ||
| 117 | set before signaling `quit'. */ | ||
| 118 | #define BYTE_CODE_QUIT \ | ||
| 119 | do { \ | ||
| 120 | if (quitcounter++) \ | ||
| 121 | break; \ | ||
| 122 | maybe_gc (); \ | ||
| 123 | if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \ | ||
| 124 | { \ | ||
| 125 | Lisp_Object flag = Vquit_flag; \ | ||
| 126 | Vquit_flag = Qnil; \ | ||
| 127 | if (EQ (Vthrow_on_input, flag)) \ | ||
| 128 | Fthrow (Vthrow_on_input, Qt); \ | ||
| 129 | quit (); \ | ||
| 130 | } \ | ||
| 131 | else if (pending_signals) \ | ||
| 132 | process_pending_signals (); \ | ||
| 133 | } while (0) | ||
| 134 | |||
| 135 | |||
| 136 | DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0, | 110 | DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0, |
| 137 | doc: /* Function used internally in byte-compiled code. | 111 | doc: /* Function used internally in byte-compiled code. |
| 138 | The first argument, BYTESTR, is a string of byte code; | 112 | The first argument, BYTESTR, is a string of byte code; |
| @@ -182,19 +156,18 @@ exec_byte_code__ (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 182 | 156 | ||
| 183 | ptrdiff_t bytestr_length = SBYTES (bytestr); | 157 | ptrdiff_t bytestr_length = SBYTES (bytestr); |
| 184 | Lisp_Object *vectorp = XVECTOR (vector)->contents; | 158 | Lisp_Object *vectorp = XVECTOR (vector)->contents; |
| 185 | struct byte_stack stack; | ||
| 186 | 159 | ||
| 187 | stack.byte_string = bytestr; | 160 | unsigned char quitcounter = 1; |
| 188 | stack.pc = stack.byte_string_start = SDATA (bytestr); | ||
| 189 | unsigned char quitcounter = 0; | ||
| 190 | EMACS_INT stack_items = XFASTINT (maxdepth) + 1; | 161 | EMACS_INT stack_items = XFASTINT (maxdepth) + 1; |
| 191 | USE_SAFE_ALLOCA; | 162 | USE_SAFE_ALLOCA; |
| 192 | Lisp_Object *stack_base; | 163 | Lisp_Object *stack_base; |
| 193 | SAFE_ALLOCA_LISP (stack_base, stack_items); | 164 | SAFE_ALLOCA_LISP_EXTRA (stack_base, stack_items, bytestr_length); |
| 194 | Lisp_Object *stack_lim = stack_base + stack_items; | 165 | Lisp_Object *stack_lim = stack_base + stack_items; |
| 195 | Lisp_Object *top = stack_base; | 166 | Lisp_Object *top = stack_base; |
| 196 | stack.next = byte_stack_list; | 167 | memcpy (stack_lim, SDATA (bytestr), bytestr_length); |
| 197 | byte_stack_list = &stack; | 168 | void *void_stack_lim = stack_lim; |
| 169 | unsigned char const *bytestr_data = void_stack_lim; | ||
| 170 | unsigned char const *pc = bytestr_data; | ||
| 198 | ptrdiff_t count = SPECPDL_INDEX (); | 171 | ptrdiff_t count = SPECPDL_INDEX (); |
| 199 | 172 | ||
| 200 | if (!NILP (args_template)) | 173 | if (!NILP (args_template)) |
| @@ -333,15 +306,10 @@ exec_byte_code__ (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 333 | 306 | ||
| 334 | CASE (Bgotoifnil): | 307 | CASE (Bgotoifnil): |
| 335 | { | 308 | { |
| 336 | Lisp_Object v1; | 309 | Lisp_Object v1 = POP; |
| 337 | op = FETCH2; | 310 | op = FETCH2; |
| 338 | v1 = POP; | ||
| 339 | if (NILP (v1)) | 311 | if (NILP (v1)) |
| 340 | { | 312 | goto op_branch; |
| 341 | BYTE_CODE_QUIT; | ||
| 342 | CHECK_RANGE (op); | ||
| 343 | stack.pc = stack.byte_string_start + op; | ||
| 344 | } | ||
| 345 | NEXT; | 313 | NEXT; |
| 346 | } | 314 | } |
| 347 | 315 | ||
| @@ -496,86 +464,72 @@ exec_byte_code__ (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 496 | NEXT; | 464 | NEXT; |
| 497 | 465 | ||
| 498 | CASE (Bgoto): | 466 | CASE (Bgoto): |
| 499 | BYTE_CODE_QUIT; | 467 | op = FETCH2; |
| 500 | op = FETCH2; /* pc = FETCH2 loses since FETCH2 contains pc++ */ | 468 | op_branch: |
| 501 | CHECK_RANGE (op); | 469 | op -= pc - bytestr_data; |
| 502 | stack.pc = stack.byte_string_start + op; | 470 | op_relative_branch: |
| 471 | if (BYTE_CODE_SAFE | ||
| 472 | && ! (bytestr_data - pc <= op | ||
| 473 | && op < bytestr_data + bytestr_length - pc)) | ||
| 474 | emacs_abort (); | ||
| 475 | quitcounter += op < 0; | ||
| 476 | if (!quitcounter) | ||
| 477 | { | ||
| 478 | quitcounter = 1; | ||
| 479 | maybe_gc (); | ||
| 480 | maybe_quit (); | ||
| 481 | } | ||
| 482 | pc += op; | ||
| 503 | NEXT; | 483 | NEXT; |
| 504 | 484 | ||
| 505 | CASE (Bgotoifnonnil): | 485 | CASE (Bgotoifnonnil): |
| 506 | op = FETCH2; | 486 | op = FETCH2; |
| 507 | Lisp_Object v1 = POP; | 487 | if (!NILP (POP)) |
| 508 | if (!NILP (v1)) | 488 | goto op_branch; |
| 509 | { | ||
| 510 | BYTE_CODE_QUIT; | ||
| 511 | CHECK_RANGE (op); | ||
| 512 | stack.pc = stack.byte_string_start + op; | ||
| 513 | } | ||
| 514 | NEXT; | 489 | NEXT; |
| 515 | 490 | ||
| 516 | CASE (Bgotoifnilelsepop): | 491 | CASE (Bgotoifnilelsepop): |
| 517 | op = FETCH2; | 492 | op = FETCH2; |
| 518 | if (NILP (TOP)) | 493 | if (NILP (TOP)) |
| 519 | { | 494 | goto op_branch; |
| 520 | BYTE_CODE_QUIT; | 495 | DISCARD (1); |
| 521 | CHECK_RANGE (op); | ||
| 522 | stack.pc = stack.byte_string_start + op; | ||
| 523 | } | ||
| 524 | else DISCARD (1); | ||
| 525 | NEXT; | 496 | NEXT; |
| 526 | 497 | ||
| 527 | CASE (Bgotoifnonnilelsepop): | 498 | CASE (Bgotoifnonnilelsepop): |
| 528 | op = FETCH2; | 499 | op = FETCH2; |
| 529 | if (!NILP (TOP)) | 500 | if (!NILP (TOP)) |
| 530 | { | 501 | goto op_branch; |
| 531 | BYTE_CODE_QUIT; | 502 | DISCARD (1); |
| 532 | CHECK_RANGE (op); | ||
| 533 | stack.pc = stack.byte_string_start + op; | ||
| 534 | } | ||
| 535 | else DISCARD (1); | ||
| 536 | NEXT; | 503 | NEXT; |
| 537 | 504 | ||
| 538 | CASE (BRgoto): | 505 | CASE (BRgoto): |
| 539 | BYTE_CODE_QUIT; | 506 | op = FETCH - 128; |
| 540 | stack.pc += (int) *stack.pc - 127; | 507 | goto op_relative_branch; |
| 541 | NEXT; | ||
| 542 | 508 | ||
| 543 | CASE (BRgotoifnil): | 509 | CASE (BRgotoifnil): |
| 510 | op = FETCH - 128; | ||
| 544 | if (NILP (POP)) | 511 | if (NILP (POP)) |
| 545 | { | 512 | goto op_relative_branch; |
| 546 | BYTE_CODE_QUIT; | ||
| 547 | stack.pc += (int) *stack.pc - 128; | ||
| 548 | } | ||
| 549 | stack.pc++; | ||
| 550 | NEXT; | 513 | NEXT; |
| 551 | 514 | ||
| 552 | CASE (BRgotoifnonnil): | 515 | CASE (BRgotoifnonnil): |
| 516 | op = FETCH - 128; | ||
| 553 | if (!NILP (POP)) | 517 | if (!NILP (POP)) |
| 554 | { | 518 | goto op_relative_branch; |
| 555 | BYTE_CODE_QUIT; | ||
| 556 | stack.pc += (int) *stack.pc - 128; | ||
| 557 | } | ||
| 558 | stack.pc++; | ||
| 559 | NEXT; | 519 | NEXT; |
| 560 | 520 | ||
| 561 | CASE (BRgotoifnilelsepop): | 521 | CASE (BRgotoifnilelsepop): |
| 562 | op = *stack.pc++; | 522 | op = FETCH - 128; |
| 563 | if (NILP (TOP)) | 523 | if (NILP (TOP)) |
| 564 | { | 524 | goto op_relative_branch; |
| 565 | BYTE_CODE_QUIT; | 525 | DISCARD (1); |
| 566 | stack.pc += op - 128; | ||
| 567 | } | ||
| 568 | else DISCARD (1); | ||
| 569 | NEXT; | 526 | NEXT; |
| 570 | 527 | ||
| 571 | CASE (BRgotoifnonnilelsepop): | 528 | CASE (BRgotoifnonnilelsepop): |
| 572 | op = *stack.pc++; | 529 | op = FETCH - 128; |
| 573 | if (!NILP (TOP)) | 530 | if (!NILP (TOP)) |
| 574 | { | 531 | goto op_relative_branch; |
| 575 | BYTE_CODE_QUIT; | 532 | DISCARD (1); |
| 576 | stack.pc += op - 128; | ||
| 577 | } | ||
| 578 | else DISCARD (1); | ||
| 579 | NEXT; | 533 | NEXT; |
| 580 | 534 | ||
| 581 | CASE (Breturn): | 535 | CASE (Breturn): |
| @@ -635,15 +589,11 @@ exec_byte_code__ (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 635 | if (sys_setjmp (c->jmp)) | 589 | if (sys_setjmp (c->jmp)) |
| 636 | { | 590 | { |
| 637 | struct handler *c = handlerlist; | 591 | struct handler *c = handlerlist; |
| 638 | int dest; | ||
| 639 | top = c->bytecode_top; | 592 | top = c->bytecode_top; |
| 640 | dest = c->bytecode_dest; | 593 | op = c->bytecode_dest; |
| 641 | handlerlist = c->next; | 594 | handlerlist = c->next; |
| 642 | PUSH (c->val); | 595 | PUSH (c->val); |
| 643 | CHECK_RANGE (dest); | 596 | goto op_branch; |
| 644 | /* Might have been re-set by longjmp! */ | ||
| 645 | stack.byte_string_start = SDATA (stack.byte_string); | ||
| 646 | stack.pc = stack.byte_string_start + dest; | ||
| 647 | } | 597 | } |
| 648 | 598 | ||
| 649 | NEXT; | 599 | NEXT; |
| @@ -657,7 +607,7 @@ exec_byte_code__ (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 657 | { | 607 | { |
| 658 | Lisp_Object handler = POP; | 608 | Lisp_Object handler = POP; |
| 659 | /* Support for a function here is new in 24.4. */ | 609 | /* Support for a function here is new in 24.4. */ |
| 660 | record_unwind_protect (FUNCTIONP (handler) ? bcall0 : unwind_body, | 610 | record_unwind_protect (FUNCTIONP (handler) ? bcall0 : prog_ignore, |
| 661 | handler); | 611 | handler); |
| 662 | NEXT; | 612 | NEXT; |
| 663 | } | 613 | } |
| @@ -1086,9 +1036,9 @@ exec_byte_code__ (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 1086 | 1036 | ||
| 1087 | CASE (Bdowncase): | 1037 | CASE (Bdowncase): |
| 1088 | TOP = Fdowncase (TOP); | 1038 | TOP = Fdowncase (TOP); |
| 1089 | NEXT; | 1039 | NEXT; |
| 1090 | 1040 | ||
| 1091 | CASE (Bstringeqlsign): | 1041 | CASE (Bstringeqlsign): |
| 1092 | { | 1042 | { |
| 1093 | Lisp_Object v1 = POP; | 1043 | Lisp_Object v1 = POP; |
| 1094 | TOP = Fstring_equal (TOP, v1); | 1044 | TOP = Fstring_equal (TOP, v1); |
| @@ -1211,7 +1161,7 @@ exec_byte_code__ (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 1211 | call3 (Qerror, | 1161 | call3 (Qerror, |
| 1212 | build_string ("Invalid byte opcode: op=%s, ptr=%d"), | 1162 | build_string ("Invalid byte opcode: op=%s, ptr=%d"), |
| 1213 | make_number (op), | 1163 | make_number (op), |
| 1214 | make_number (stack.pc - 1 - stack.byte_string_start)); | 1164 | make_number (pc - 1 - bytestr_data)); |
| 1215 | 1165 | ||
| 1216 | /* Handy byte-codes for lexical binding. */ | 1166 | /* Handy byte-codes for lexical binding. */ |
| 1217 | CASE (Bstack_ref1): | 1167 | CASE (Bstack_ref1): |
| @@ -1271,8 +1221,6 @@ exec_byte_code__ (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 1271 | 1221 | ||
| 1272 | exit: | 1222 | exit: |
| 1273 | 1223 | ||
| 1274 | byte_stack_list = byte_stack_list->next; | ||
| 1275 | |||
| 1276 | /* Binds and unbinds are supposed to be compiled balanced. */ | 1224 | /* Binds and unbinds are supposed to be compiled balanced. */ |
| 1277 | if (SPECPDL_INDEX () != count) | 1225 | if (SPECPDL_INDEX () != count) |
| 1278 | { | 1226 | { |