diff options
Diffstat (limited to 'src/bytecode.c')
| -rw-r--r-- | src/bytecode.c | 91 |
1 files changed, 86 insertions, 5 deletions
diff --git a/src/bytecode.c b/src/bytecode.c index 29b76f88ef7..fe59cf6600b 100644 --- a/src/bytecode.c +++ b/src/bytecode.c | |||
| @@ -311,8 +311,6 @@ enum byte_code_op | |||
| 311 | 311 | ||
| 312 | #define TOP (*top) | 312 | #define TOP (*top) |
| 313 | 313 | ||
| 314 | #define UPDATE_OFFSET (backtrace_byte_offset = pc - bytestr_data); | ||
| 315 | |||
| 316 | DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0, | 314 | DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0, |
| 317 | doc: /* Function used internally in byte-compiled code. | 315 | doc: /* Function used internally in byte-compiled code. |
| 318 | The first argument, BYTESTR, is a string of byte code; | 316 | The first argument, BYTESTR, is a string of byte code; |
| @@ -433,7 +431,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 433 | /* NEXT is invoked at the end of an instruction to go to the | 431 | /* NEXT is invoked at the end of an instruction to go to the |
| 434 | next instruction. It is either a computed goto, or a | 432 | next instruction. It is either a computed goto, or a |
| 435 | plain break. */ | 433 | plain break. */ |
| 436 | #define NEXT UPDATE_OFFSET goto *(targets[op = FETCH]) | 434 | #define NEXT goto *(targets[op = FETCH]) |
| 437 | /* FIRST is like NEXT, but is only used at the start of the | 435 | /* FIRST is like NEXT, but is only used at the start of the |
| 438 | interpreter body. In the switch-based interpreter it is the | 436 | interpreter body. In the switch-based interpreter it is the |
| 439 | switch, so the threaded definition must include a semicolon. */ | 437 | switch, so the threaded definition must include a semicolon. */ |
| @@ -635,7 +633,90 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 635 | } | 633 | } |
| 636 | } | 634 | } |
| 637 | #endif | 635 | #endif |
| 638 | TOP = Ffuncall (op + 1, &TOP); | 636 | Lisp_Object fun, original_fun; |
| 637 | Lisp_Object funcar; | ||
| 638 | Lisp_Object *fun_args; | ||
| 639 | ptrdiff_t numargs = op; | ||
| 640 | Lisp_Object val; | ||
| 641 | ptrdiff_t count_c; | ||
| 642 | |||
| 643 | maybe_quit (); | ||
| 644 | |||
| 645 | if (++lisp_eval_depth > max_lisp_eval_depth) | ||
| 646 | { | ||
| 647 | if (max_lisp_eval_depth < 100) | ||
| 648 | max_lisp_eval_depth = 100; | ||
| 649 | if (lisp_eval_depth > max_lisp_eval_depth) | ||
| 650 | error ("Lisp nesting exceeds `max-lisp-eval-depth'"); | ||
| 651 | } | ||
| 652 | |||
| 653 | fun_args = &TOP + 1; | ||
| 654 | |||
| 655 | count_c = record_in_backtrace_with_offset (TOP, fun_args, numargs, pc - bytestr_data - 1); | ||
| 656 | |||
| 657 | maybe_gc (); | ||
| 658 | |||
| 659 | if (debug_on_next_call) | ||
| 660 | do_debug_on_call (Qlambda, count); | ||
| 661 | |||
| 662 | original_fun = TOP; | ||
| 663 | |||
| 664 | retry: | ||
| 665 | |||
| 666 | /* Optimize for no indirection. */ | ||
| 667 | fun = original_fun; | ||
| 668 | if (SYMBOLP (fun) && !NILP (fun) | ||
| 669 | && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun))) | ||
| 670 | fun = indirect_function (fun); | ||
| 671 | |||
| 672 | if (COMPILEDP (fun)) | ||
| 673 | { | ||
| 674 | Lisp_Object syms_left = AREF (fun, COMPILED_ARGLIST); | ||
| 675 | if (FIXNUMP (syms_left)) | ||
| 676 | { | ||
| 677 | if (CONSP (AREF (fun, COMPILED_BYTECODE))) | ||
| 678 | Ffetch_bytecode (fun); | ||
| 679 | val = exec_byte_code (AREF (fun, COMPILED_BYTECODE), | ||
| 680 | AREF (fun, COMPILED_CONSTANTS), | ||
| 681 | AREF (fun, COMPILED_STACK_DEPTH), | ||
| 682 | syms_left, numargs, fun_args); | ||
| 683 | } | ||
| 684 | else | ||
| 685 | { | ||
| 686 | /* The rest of funcall_lambda is very bulky */ | ||
| 687 | val = funcall_lambda (fun, numargs, fun_args); | ||
| 688 | } | ||
| 689 | } | ||
| 690 | else if (SUBRP (fun)) | ||
| 691 | val = funcall_subr (XSUBR (fun), numargs, fun_args); | ||
| 692 | #ifdef HAVE_MODULES | ||
| 693 | else if (MODULE_FUNCTIONP (fun)) | ||
| 694 | val = funcall_module (fun, numargs, fun_args); | ||
| 695 | #endif | ||
| 696 | else | ||
| 697 | { | ||
| 698 | if (NILP (fun)) | ||
| 699 | xsignal1 (Qvoid_function, original_fun); | ||
| 700 | if (!CONSP (fun) | ||
| 701 | || (funcar = XCAR (fun), !SYMBOLP(funcar))) | ||
| 702 | xsignal1 (Qinvalid_function, original_fun); | ||
| 703 | if (EQ (funcar, Qlambda) | ||
| 704 | || EQ (funcar, Qclosure)) | ||
| 705 | val = funcall_lambda (fun, numargs, fun_args); | ||
| 706 | else if (EQ (funcar, Qautoload)) | ||
| 707 | { | ||
| 708 | Fautoload_do_load (fun, original_fun, Qnil); | ||
| 709 | goto retry; | ||
| 710 | } | ||
| 711 | else | ||
| 712 | xsignal1 (Qinvalid_function, original_fun); | ||
| 713 | } | ||
| 714 | lisp_eval_depth--; | ||
| 715 | if (backtrace_debug_on_exit (specpdl + count_c)) | ||
| 716 | val = call_debugger (list2 (Qexit, val)); | ||
| 717 | specpdl_ptr--; | ||
| 718 | |||
| 719 | TOP = val; | ||
| 639 | NEXT; | 720 | NEXT; |
| 640 | } | 721 | } |
| 641 | 722 | ||
| @@ -1451,7 +1532,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 1451 | unbind_to (count, Qnil); | 1532 | unbind_to (count, Qnil); |
| 1452 | error ("binding stack not balanced (serious byte compiler bug)"); | 1533 | error ("binding stack not balanced (serious byte compiler bug)"); |
| 1453 | } | 1534 | } |
| 1454 | backtrace_byte_offset = -1; | 1535 | |
| 1455 | Lisp_Object result = TOP; | 1536 | Lisp_Object result = TOP; |
| 1456 | SAFE_FREE (); | 1537 | SAFE_FREE (); |
| 1457 | return result; | 1538 | return result; |