diff options
Diffstat (limited to 'src/bytecode.c')
| -rw-r--r-- | src/bytecode.c | 400 |
1 files changed, 266 insertions, 134 deletions
diff --git a/src/bytecode.c b/src/bytecode.c index bda9a39b7f3..2b1eccdc518 100644 --- a/src/bytecode.c +++ b/src/bytecode.c | |||
| @@ -21,6 +21,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 21 | 21 | ||
| 22 | #include "lisp.h" | 22 | #include "lisp.h" |
| 23 | #include "blockinput.h" | 23 | #include "blockinput.h" |
| 24 | #include "sysstdio.h" | ||
| 24 | #include "character.h" | 25 | #include "character.h" |
| 25 | #include "buffer.h" | 26 | #include "buffer.h" |
| 26 | #include "keyboard.h" | 27 | #include "keyboard.h" |
| @@ -175,8 +176,8 @@ DEFINE (Bmin, 0136) \ | |||
| 175 | DEFINE (Bmult, 0137) \ | 176 | DEFINE (Bmult, 0137) \ |
| 176 | \ | 177 | \ |
| 177 | DEFINE (Bpoint, 0140) \ | 178 | DEFINE (Bpoint, 0140) \ |
| 178 | /* Was Bmark in v17. */ \ | 179 | /* 0141 was Bmark in v17, Bsave_current_buffer in 18-19. */ \ |
| 179 | DEFINE (Bsave_current_buffer, 0141) /* Obsolete. */ \ | 180 | DEFINE (Bsave_current_buffer_OBSOLETE, 0141) /* Obsolete since 20. */ \ |
| 180 | DEFINE (Bgoto_char, 0142) \ | 181 | DEFINE (Bgoto_char, 0142) \ |
| 181 | DEFINE (Binsert, 0143) \ | 182 | DEFINE (Binsert, 0143) \ |
| 182 | DEFINE (Bpoint_max, 0144) \ | 183 | DEFINE (Bpoint_max, 0144) \ |
| @@ -186,13 +187,15 @@ DEFINE (Bfollowing_char, 0147) \ | |||
| 186 | DEFINE (Bpreceding_char, 0150) \ | 187 | DEFINE (Bpreceding_char, 0150) \ |
| 187 | DEFINE (Bcurrent_column, 0151) \ | 188 | DEFINE (Bcurrent_column, 0151) \ |
| 188 | DEFINE (Bindent_to, 0152) \ | 189 | DEFINE (Bindent_to, 0152) \ |
| 190 | /* 0153 was Bscan_buffer in v17. */ \ | ||
| 189 | DEFINE (Beolp, 0154) \ | 191 | DEFINE (Beolp, 0154) \ |
| 190 | DEFINE (Beobp, 0155) \ | 192 | DEFINE (Beobp, 0155) \ |
| 191 | DEFINE (Bbolp, 0156) \ | 193 | DEFINE (Bbolp, 0156) \ |
| 192 | DEFINE (Bbobp, 0157) \ | 194 | DEFINE (Bbobp, 0157) \ |
| 193 | DEFINE (Bcurrent_buffer, 0160) \ | 195 | DEFINE (Bcurrent_buffer, 0160) \ |
| 194 | DEFINE (Bset_buffer, 0161) \ | 196 | DEFINE (Bset_buffer, 0161) \ |
| 195 | DEFINE (Bsave_current_buffer_1, 0162) /* Replacing Bsave_current_buffer. */ \ | 197 | DEFINE (Bsave_current_buffer, 0162) \ |
| 198 | /* 0163 was Bset_mark in v17. */ \ | ||
| 196 | DEFINE (Binteractive_p, 0164) /* Obsolete since Emacs-24.1. */ \ | 199 | DEFINE (Binteractive_p, 0164) /* Obsolete since Emacs-24.1. */ \ |
| 197 | \ | 200 | \ |
| 198 | DEFINE (Bforward_char, 0165) \ | 201 | DEFINE (Bforward_char, 0165) \ |
| @@ -253,11 +256,7 @@ DEFINE (Brem, 0246) \ | |||
| 253 | DEFINE (Bnumberp, 0247) \ | 256 | DEFINE (Bnumberp, 0247) \ |
| 254 | DEFINE (Bintegerp, 0250) \ | 257 | DEFINE (Bintegerp, 0250) \ |
| 255 | \ | 258 | \ |
| 256 | DEFINE (BRgoto, 0252) \ | 259 | /* 0252-0256 were relative jumps, apparently never used. */ \ |
| 257 | DEFINE (BRgotoifnil, 0253) \ | ||
| 258 | DEFINE (BRgotoifnonnil, 0254) \ | ||
| 259 | DEFINE (BRgotoifnilelsepop, 0255) \ | ||
| 260 | DEFINE (BRgotoifnonnilelsepop, 0256) \ | ||
| 261 | \ | 260 | \ |
| 262 | DEFINE (BlistN, 0257) \ | 261 | DEFINE (BlistN, 0257) \ |
| 263 | DEFINE (BconcatN, 0260) \ | 262 | DEFINE (BconcatN, 0260) \ |
| @@ -277,11 +276,6 @@ enum byte_code_op | |||
| 277 | #define DEFINE(name, value) name = value, | 276 | #define DEFINE(name, value) name = value, |
| 278 | BYTE_CODES | 277 | BYTE_CODES |
| 279 | #undef DEFINE | 278 | #undef DEFINE |
| 280 | |||
| 281 | #if BYTE_CODE_SAFE | ||
| 282 | Bscan_buffer = 0153, /* No longer generated as of v18. */ | ||
| 283 | Bset_mark = 0163, /* this loser is no longer generated as of v18 */ | ||
| 284 | #endif | ||
| 285 | }; | 279 | }; |
| 286 | 280 | ||
| 287 | /* Fetch the next byte from the bytecode stream. */ | 281 | /* Fetch the next byte from the bytecode stream. */ |
| @@ -291,7 +285,7 @@ enum byte_code_op | |||
| 291 | /* Fetch two bytes from the bytecode stream and make a 16-bit number | 285 | /* Fetch two bytes from the bytecode stream and make a 16-bit number |
| 292 | out of them. */ | 286 | out of them. */ |
| 293 | 287 | ||
| 294 | #define FETCH2 (op = FETCH, op + (FETCH << 8)) | 288 | #define FETCH2 (op = FETCH, op | (FETCH << 8)) |
| 295 | 289 | ||
| 296 | /* Push X onto the execution stack. The expression X should not | 290 | /* Push X onto the execution stack. The expression X should not |
| 297 | contain TOP, to avoid competing side effects. */ | 291 | contain TOP, to avoid competing side effects. */ |
| @@ -331,9 +325,8 @@ If the third argument is incorrect, Emacs may crash. */) | |||
| 331 | the original unibyte form. */ | 325 | the original unibyte form. */ |
| 332 | bytestr = Fstring_as_unibyte (bytestr); | 326 | bytestr = Fstring_as_unibyte (bytestr); |
| 333 | } | 327 | } |
| 334 | pin_string (bytestr); // Bytecode must be immovable. | 328 | Lisp_Object fun = CALLN (Fmake_byte_code, Qnil, bytestr, vector, maxdepth); |
| 335 | 329 | return exec_byte_code (fun, 0, 0, NULL); | |
| 336 | return exec_byte_code (bytestr, vector, maxdepth, 0, 0, NULL); | ||
| 337 | } | 330 | } |
| 338 | 331 | ||
| 339 | static void | 332 | static void |
| @@ -342,48 +335,186 @@ bcall0 (Lisp_Object f) | |||
| 342 | Ffuncall (1, &f); | 335 | Ffuncall (1, &f); |
| 343 | } | 336 | } |
| 344 | 337 | ||
| 345 | /* Execute the byte-code in BYTESTR. VECTOR is the constant vector, and | 338 | /* The bytecode stack size in bytes. |
| 346 | MAXDEPTH is the maximum stack depth used (if MAXDEPTH is incorrect, | 339 | This is a fairly generous amount, but: |
| 347 | emacs may crash!). ARGS_TEMPLATE is the function arity encoded as an | 340 | - if users need more, we could allocate more, or just reserve the address |
| 348 | integer, and ARGS, of size NARGS, should be a vector of the actual | 341 | space and allocate on demand |
| 349 | arguments. The arguments in ARGS are pushed on the stack according | 342 | - if threads are used more, then it might be a good idea to reduce the |
| 350 | to ARGS_TEMPLATE before executing BYTESTR. */ | 343 | per-thread overhead in time and space |
| 344 | - for maximum flexibility but a small runtime penalty, we could allocate | ||
| 345 | the stack in smaller chunks as needed | ||
| 346 | */ | ||
| 347 | #define BC_STACK_SIZE (512 * 1024 * sizeof (Lisp_Object)) | ||
| 348 | |||
| 349 | /* Bytecode interpreter stack: | ||
| 350 | |||
| 351 | |--------------| -- | ||
| 352 | |fun | | ^ stack growth | ||
| 353 | |saved_pc | | | direction | ||
| 354 | |saved_top ------- | | ||
| 355 | fp--->|saved_fp ---- | | current frame | ||
| 356 | |--------------| | | | (called from bytecode in this example) | ||
| 357 | | (free) | | | | | ||
| 358 | top-->| ...stack... | | | | | ||
| 359 | : ... : | | | | ||
| 360 | |incoming args | | | | | ||
| 361 | |--------------| | | -- | ||
| 362 | |fun | | | | | ||
| 363 | |saved_pc | | | | | ||
| 364 | |saved_top | | | | | ||
| 365 | |saved_fp |<- | | previous frame | ||
| 366 | |--------------| | | | ||
| 367 | | (free) | | | | ||
| 368 | | ...stack... |<---- | | ||
| 369 | : ... : | | ||
| 370 | |incoming args | | | ||
| 371 | |--------------| -- | ||
| 372 | : : | ||
| 373 | */ | ||
| 374 | |||
| 375 | /* bytecode stack frame header (footer, actually) */ | ||
| 376 | struct bc_frame { | ||
| 377 | struct bc_frame *saved_fp; /* previous frame pointer, | ||
| 378 | NULL if bottommost frame */ | ||
| 379 | |||
| 380 | /* In a frame called directly from C, the following two members are NULL. */ | ||
| 381 | Lisp_Object *saved_top; /* previous stack pointer */ | ||
| 382 | const unsigned char *saved_pc; /* previous program counter */ | ||
| 383 | |||
| 384 | Lisp_Object fun; /* current function object */ | ||
| 385 | |||
| 386 | Lisp_Object next_stack[]; /* data stack of next frame */ | ||
| 387 | }; | ||
| 388 | |||
| 389 | void | ||
| 390 | init_bc_thread (struct bc_thread_state *bc) | ||
| 391 | { | ||
| 392 | bc->stack = xmalloc (BC_STACK_SIZE); | ||
| 393 | bc->stack_end = bc->stack + BC_STACK_SIZE; | ||
| 394 | /* Put a dummy header at the bottom to indicate the first free location. */ | ||
| 395 | bc->fp = (struct bc_frame *)bc->stack; | ||
| 396 | memset (bc->fp, 0, sizeof *bc->fp); | ||
| 397 | } | ||
| 398 | |||
| 399 | void | ||
| 400 | free_bc_thread (struct bc_thread_state *bc) | ||
| 401 | { | ||
| 402 | xfree (bc->stack); | ||
| 403 | } | ||
| 404 | |||
| 405 | void | ||
| 406 | mark_bytecode (struct bc_thread_state *bc) | ||
| 407 | { | ||
| 408 | struct bc_frame *fp = bc->fp; | ||
| 409 | Lisp_Object *top = NULL; /* stack pointer of topmost frame not known */ | ||
| 410 | for (;;) | ||
| 411 | { | ||
| 412 | struct bc_frame *next_fp = fp->saved_fp; | ||
| 413 | /* Only the dummy frame at the bottom has saved_fp = NULL. */ | ||
| 414 | if (!next_fp) | ||
| 415 | break; | ||
| 416 | mark_object (fp->fun); | ||
| 417 | Lisp_Object *frame_base = next_fp->next_stack; | ||
| 418 | if (top) | ||
| 419 | { | ||
| 420 | /* The stack pointer of a frame is known: mark the part of the stack | ||
| 421 | above it conservatively. This includes any outgoing arguments. */ | ||
| 422 | mark_memory (top + 1, fp); | ||
| 423 | /* Mark the rest of the stack precisely. */ | ||
| 424 | mark_objects (frame_base, top + 1 - frame_base); | ||
| 425 | } | ||
| 426 | else | ||
| 427 | { | ||
| 428 | /* The stack pointer is unknown -- mark everything conservatively. */ | ||
| 429 | mark_memory (frame_base, fp); | ||
| 430 | } | ||
| 431 | top = fp->saved_top; | ||
| 432 | fp = next_fp; | ||
| 433 | } | ||
| 434 | } | ||
| 435 | |||
| 436 | DEFUN ("internal-stack-stats", Finternal_stack_stats, Sinternal_stack_stats, | ||
| 437 | 0, 0, 0, | ||
| 438 | doc: /* internal */) | ||
| 439 | (void) | ||
| 440 | { | ||
| 441 | struct bc_thread_state *bc = ¤t_thread->bc; | ||
| 442 | int nframes = 0; | ||
| 443 | int nruns = 0; | ||
| 444 | for (struct bc_frame *fp = bc->fp; fp; fp = fp->saved_fp) | ||
| 445 | { | ||
| 446 | nframes++; | ||
| 447 | if (fp->saved_top == NULL) | ||
| 448 | nruns++; | ||
| 449 | } | ||
| 450 | fprintf (stderr, "%d stack frames, %d runs\n", nframes, nruns); | ||
| 451 | return Qnil; | ||
| 452 | } | ||
| 453 | |||
| 454 | /* Whether a stack pointer is valid in the current frame. */ | ||
| 455 | static bool | ||
| 456 | valid_sp (struct bc_thread_state *bc, Lisp_Object *sp) | ||
| 457 | { | ||
| 458 | struct bc_frame *fp = bc->fp; | ||
| 459 | return sp < (Lisp_Object *)fp && sp + 1 >= fp->saved_fp->next_stack; | ||
| 460 | } | ||
| 461 | |||
| 462 | /* Execute the byte-code in FUN. ARGS_TEMPLATE is the function arity | ||
| 463 | encoded as an integer (the one in FUN is ignored), and ARGS, of | ||
| 464 | size NARGS, should be a vector of the actual arguments. The | ||
| 465 | arguments in ARGS are pushed on the stack according to | ||
| 466 | ARGS_TEMPLATE before executing FUN. */ | ||
| 351 | 467 | ||
| 352 | Lisp_Object | 468 | Lisp_Object |
| 353 | exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | 469 | exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, |
| 354 | ptrdiff_t args_template, ptrdiff_t nargs, Lisp_Object *args) | 470 | ptrdiff_t nargs, Lisp_Object *args) |
| 355 | { | 471 | { |
| 356 | #ifdef BYTE_CODE_METER | 472 | #ifdef BYTE_CODE_METER |
| 357 | int volatile this_op = 0; | 473 | int volatile this_op = 0; |
| 358 | #endif | 474 | #endif |
| 475 | unsigned char quitcounter = 1; | ||
| 476 | struct bc_thread_state *bc = ¤t_thread->bc; | ||
| 477 | |||
| 478 | /* Values used for the first stack record when called from C. */ | ||
| 479 | Lisp_Object *top = NULL; | ||
| 480 | unsigned char const *pc = NULL; | ||
| 359 | 481 | ||
| 482 | Lisp_Object bytestr = AREF (fun, COMPILED_BYTECODE); | ||
| 483 | |||
| 484 | setup_frame: ; | ||
| 360 | eassert (!STRING_MULTIBYTE (bytestr)); | 485 | eassert (!STRING_MULTIBYTE (bytestr)); |
| 361 | eassert (string_immovable_p (bytestr)); | 486 | eassert (string_immovable_p (bytestr)); |
| 487 | /* FIXME: in debug mode (!NDEBUG, BYTE_CODE_SAFE or enabled checking), | ||
| 488 | save the specpdl index on function entry and check that it is the same | ||
| 489 | when returning, to detect unwind imbalances. This would require adding | ||
| 490 | a field to the frame header. */ | ||
| 362 | 491 | ||
| 492 | Lisp_Object vector = AREF (fun, COMPILED_CONSTANTS); | ||
| 493 | Lisp_Object maxdepth = AREF (fun, COMPILED_STACK_DEPTH); | ||
| 363 | ptrdiff_t const_length = ASIZE (vector); | 494 | ptrdiff_t const_length = ASIZE (vector); |
| 364 | ptrdiff_t bytestr_length = SCHARS (bytestr); | 495 | ptrdiff_t bytestr_length = SCHARS (bytestr); |
| 365 | Lisp_Object *vectorp = XVECTOR (vector)->contents; | 496 | Lisp_Object *vectorp = XVECTOR (vector)->contents; |
| 366 | 497 | ||
| 367 | unsigned char quitcounter = 1; | 498 | EMACS_INT max_stack = XFIXNAT (maxdepth); |
| 368 | /* Allocate two more slots than required, because... */ | 499 | Lisp_Object *frame_base = bc->fp->next_stack; |
| 369 | EMACS_INT stack_items = XFIXNAT (maxdepth) + 2; | 500 | struct bc_frame *fp = (struct bc_frame *)(frame_base + max_stack); |
| 370 | USE_SAFE_ALLOCA; | 501 | |
| 371 | void *alloc; | 502 | if ((char *)fp->next_stack > bc->stack_end) |
| 372 | SAFE_ALLOCA_LISP (alloc, stack_items); | 503 | error ("Bytecode stack overflow"); |
| 373 | Lisp_Object *stack_base = alloc; | 504 | |
| 374 | /* ... we plonk BYTESTR and VECTOR there to ensure that they survive | 505 | /* Save the function object so that the bytecode and vector are |
| 375 | GC (bug#33014), since these variables aren't used directly beyond | 506 | held from removal by the GC. */ |
| 376 | the interpreter prologue and wouldn't be found in the stack frame | 507 | fp->fun = fun; |
| 377 | otherwise. */ | 508 | /* Save previous stack pointer and pc in the new frame. If we came |
| 378 | stack_base[0] = bytestr; | 509 | directly from outside, these will be NULL. */ |
| 379 | stack_base[1] = vector; | 510 | fp->saved_top = top; |
| 380 | Lisp_Object *top = stack_base + 1; | 511 | fp->saved_pc = pc; |
| 381 | Lisp_Object *stack_lim = top + stack_items; | 512 | fp->saved_fp = bc->fp; |
| 513 | bc->fp = fp; | ||
| 514 | |||
| 515 | top = frame_base - 1; | ||
| 382 | unsigned char const *bytestr_data = SDATA (bytestr); | 516 | unsigned char const *bytestr_data = SDATA (bytestr); |
| 383 | unsigned char const *pc = bytestr_data; | 517 | pc = bytestr_data; |
| 384 | #if BYTE_CODE_SAFE || !defined NDEBUG | ||
| 385 | specpdl_ref count = SPECPDL_INDEX (); | ||
| 386 | #endif | ||
| 387 | 518 | ||
| 388 | /* ARGS_TEMPLATE is composed of bit fields: | 519 | /* ARGS_TEMPLATE is composed of bit fields: |
| 389 | bits 0..6 minimum number of arguments | 520 | bits 0..6 minimum number of arguments |
| @@ -410,7 +541,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 410 | int op; | 541 | int op; |
| 411 | enum handlertype type; | 542 | enum handlertype type; |
| 412 | 543 | ||
| 413 | if (BYTE_CODE_SAFE && ! (stack_base <= top && top < stack_lim)) | 544 | if (BYTE_CODE_SAFE && !valid_sp (bc, top)) |
| 414 | emacs_abort (); | 545 | emacs_abort (); |
| 415 | 546 | ||
| 416 | #ifdef BYTE_CODE_METER | 547 | #ifdef BYTE_CODE_METER |
| @@ -458,17 +589,13 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 458 | 589 | ||
| 459 | #ifdef BYTE_CODE_THREADED | 590 | #ifdef BYTE_CODE_THREADED |
| 460 | 591 | ||
| 461 | /* A convenience define that saves us a lot of typing and makes | ||
| 462 | the table clearer. */ | ||
| 463 | #define LABEL(OP) [OP] = &&insn_ ## OP | ||
| 464 | |||
| 465 | /* This is the dispatch table for the threaded interpreter. */ | 592 | /* This is the dispatch table for the threaded interpreter. */ |
| 466 | static const void *const targets[256] = | 593 | static const void *const targets[256] = |
| 467 | { | 594 | { |
| 468 | [0 ... (Bconstant - 1)] = &&insn_default, | 595 | [0 ... (Bconstant - 1)] = &&insn_default, |
| 469 | [Bconstant ... 255] = &&insn_Bconstant, | 596 | [Bconstant ... 255] = &&insn_Bconstant, |
| 470 | 597 | ||
| 471 | #define DEFINE(name, value) LABEL (name) , | 598 | #define DEFINE(name, value) [name] = &&insn_ ## name, |
| 472 | BYTE_CODES | 599 | BYTE_CODES |
| 473 | #undef DEFINE | 600 | #undef DEFINE |
| 474 | }; | 601 | }; |
| @@ -500,7 +627,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 500 | Lisp_Object v1 = vectorp[op], v2; | 627 | Lisp_Object v1 = vectorp[op], v2; |
| 501 | if (!SYMBOLP (v1) | 628 | if (!SYMBOLP (v1) |
| 502 | || XSYMBOL (v1)->u.s.redirect != SYMBOL_PLAINVAL | 629 | || XSYMBOL (v1)->u.s.redirect != SYMBOL_PLAINVAL |
| 503 | || (v2 = SYMBOL_VAL (XSYMBOL (v1)), EQ (v2, Qunbound))) | 630 | || (v2 = SYMBOL_VAL (XSYMBOL (v1)), BASE_EQ (v2, Qunbound))) |
| 504 | v2 = Fsymbol_value (v1); | 631 | v2 = Fsymbol_value (v1); |
| 505 | PUSH (v2); | 632 | PUSH (v2); |
| 506 | NEXT; | 633 | NEXT; |
| @@ -567,7 +694,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 567 | 694 | ||
| 568 | /* Inline the most common case. */ | 695 | /* Inline the most common case. */ |
| 569 | if (SYMBOLP (sym) | 696 | if (SYMBOLP (sym) |
| 570 | && !EQ (val, Qunbound) | 697 | && !BASE_EQ (val, Qunbound) |
| 571 | && XSYMBOL (sym)->u.s.redirect == SYMBOL_PLAINVAL | 698 | && XSYMBOL (sym)->u.s.redirect == SYMBOL_PLAINVAL |
| 572 | && !SYMBOL_TRAPPED_WRITE_P (sym)) | 699 | && !SYMBOL_TRAPPED_WRITE_P (sym)) |
| 573 | SET_SYMBOL_VAL (XSYMBOL (sym), val); | 700 | SET_SYMBOL_VAL (XSYMBOL (sym), val); |
| @@ -646,39 +773,45 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 646 | error ("Lisp nesting exceeds `max-lisp-eval-depth'"); | 773 | error ("Lisp nesting exceeds `max-lisp-eval-depth'"); |
| 647 | } | 774 | } |
| 648 | 775 | ||
| 649 | ptrdiff_t numargs = op; | 776 | ptrdiff_t call_nargs = op; |
| 650 | Lisp_Object fun = TOP; | 777 | Lisp_Object call_fun = TOP; |
| 651 | Lisp_Object *args = &TOP + 1; | 778 | Lisp_Object *call_args = &TOP + 1; |
| 652 | 779 | ||
| 653 | specpdl_ref count1 = record_in_backtrace (fun, args, numargs); | 780 | specpdl_ref count1 = record_in_backtrace (call_fun, |
| 781 | call_args, call_nargs); | ||
| 654 | maybe_gc (); | 782 | maybe_gc (); |
| 655 | if (debug_on_next_call) | 783 | if (debug_on_next_call) |
| 656 | do_debug_on_call (Qlambda, count1); | 784 | do_debug_on_call (Qlambda, count1); |
| 657 | 785 | ||
| 658 | Lisp_Object original_fun = fun; | 786 | Lisp_Object original_fun = call_fun; |
| 659 | if (SYMBOLP (fun)) | 787 | if (SYMBOLP (call_fun)) |
| 660 | fun = XSYMBOL (fun)->u.s.function; | 788 | call_fun = XSYMBOL (call_fun)->u.s.function; |
| 661 | Lisp_Object template; | 789 | Lisp_Object template; |
| 662 | Lisp_Object bytecode; | 790 | Lisp_Object bytecode; |
| 663 | Lisp_Object val; | 791 | if (COMPILEDP (call_fun) |
| 664 | if (COMPILEDP (fun) | ||
| 665 | // Lexical binding only. | 792 | // Lexical binding only. |
| 666 | && (template = AREF (fun, COMPILED_ARGLIST), | 793 | && (template = AREF (call_fun, COMPILED_ARGLIST), |
| 667 | FIXNUMP (template)) | 794 | FIXNUMP (template)) |
| 668 | // No autoloads. | 795 | // No autoloads. |
| 669 | && (bytecode = AREF (fun, COMPILED_BYTECODE), | 796 | && (bytecode = AREF (call_fun, COMPILED_BYTECODE), |
| 670 | !CONSP (bytecode))) | 797 | !CONSP (bytecode))) |
| 671 | val = exec_byte_code (bytecode, | 798 | { |
| 672 | AREF (fun, COMPILED_CONSTANTS), | 799 | fun = call_fun; |
| 673 | AREF (fun, COMPILED_STACK_DEPTH), | 800 | bytestr = bytecode; |
| 674 | XFIXNUM (template), numargs, args); | 801 | args_template = XFIXNUM (template); |
| 675 | else if (SUBRP (fun) && !SUBR_NATIVE_COMPILED_DYNP (fun)) | 802 | nargs = call_nargs; |
| 676 | val = funcall_subr (XSUBR (fun), numargs, args); | 803 | args = call_args; |
| 804 | goto setup_frame; | ||
| 805 | } | ||
| 806 | |||
| 807 | Lisp_Object val; | ||
| 808 | if (SUBRP (call_fun) && !SUBR_NATIVE_COMPILED_DYNP (call_fun)) | ||
| 809 | val = funcall_subr (XSUBR (call_fun), call_nargs, call_args); | ||
| 677 | else | 810 | else |
| 678 | val = funcall_general (original_fun, numargs, args); | 811 | val = funcall_general (original_fun, call_nargs, call_args); |
| 679 | 812 | ||
| 680 | lisp_eval_depth--; | 813 | lisp_eval_depth--; |
| 681 | if (backtrace_debug_on_exit (specpdl_ref_to_ptr (count1))) | 814 | if (backtrace_debug_on_exit (specpdl_ptr - 1)) |
| 682 | val = call_debugger (list2 (Qexit, val)); | 815 | val = call_debugger (list2 (Qexit, val)); |
| 683 | specpdl_ptr--; | 816 | specpdl_ptr--; |
| 684 | 817 | ||
| @@ -709,7 +842,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 709 | op = FETCH2; | 842 | op = FETCH2; |
| 710 | op_branch: | 843 | op_branch: |
| 711 | op -= pc - bytestr_data; | 844 | op -= pc - bytestr_data; |
| 712 | op_relative_branch: | ||
| 713 | if (BYTE_CODE_SAFE | 845 | if (BYTE_CODE_SAFE |
| 714 | && ! (bytestr_data - pc <= op | 846 | && ! (bytestr_data - pc <= op |
| 715 | && op < bytestr_data + bytestr_length - pc)) | 847 | && op < bytestr_data + bytestr_length - pc)) |
| @@ -744,38 +876,41 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 744 | DISCARD (1); | 876 | DISCARD (1); |
| 745 | NEXT; | 877 | NEXT; |
| 746 | 878 | ||
| 747 | CASE (BRgoto): | ||
| 748 | op = FETCH - 128; | ||
| 749 | goto op_relative_branch; | ||
| 750 | |||
| 751 | CASE (BRgotoifnil): | ||
| 752 | op = FETCH - 128; | ||
| 753 | if (NILP (POP)) | ||
| 754 | goto op_relative_branch; | ||
| 755 | NEXT; | ||
| 756 | |||
| 757 | CASE (BRgotoifnonnil): | ||
| 758 | op = FETCH - 128; | ||
| 759 | if (!NILP (POP)) | ||
| 760 | goto op_relative_branch; | ||
| 761 | NEXT; | ||
| 762 | |||
| 763 | CASE (BRgotoifnilelsepop): | ||
| 764 | op = FETCH - 128; | ||
| 765 | if (NILP (TOP)) | ||
| 766 | goto op_relative_branch; | ||
| 767 | DISCARD (1); | ||
| 768 | NEXT; | ||
| 769 | |||
| 770 | CASE (BRgotoifnonnilelsepop): | ||
| 771 | op = FETCH - 128; | ||
| 772 | if (!NILP (TOP)) | ||
| 773 | goto op_relative_branch; | ||
| 774 | DISCARD (1); | ||
| 775 | NEXT; | ||
| 776 | |||
| 777 | CASE (Breturn): | 879 | CASE (Breturn): |
| 778 | goto exit; | 880 | { |
| 881 | Lisp_Object *saved_top = bc->fp->saved_top; | ||
| 882 | if (saved_top) | ||
| 883 | { | ||
| 884 | Lisp_Object val = TOP; | ||
| 885 | |||
| 886 | lisp_eval_depth--; | ||
| 887 | if (backtrace_debug_on_exit (specpdl_ptr - 1)) | ||
| 888 | val = call_debugger (list2 (Qexit, val)); | ||
| 889 | specpdl_ptr--; | ||
| 890 | |||
| 891 | top = saved_top; | ||
| 892 | pc = bc->fp->saved_pc; | ||
| 893 | struct bc_frame *fp = bc->fp->saved_fp; | ||
| 894 | bc->fp = fp; | ||
| 895 | |||
| 896 | Lisp_Object fun = fp->fun; | ||
| 897 | Lisp_Object bytestr = AREF (fun, COMPILED_BYTECODE); | ||
| 898 | Lisp_Object vector = AREF (fun, COMPILED_CONSTANTS); | ||
| 899 | bytestr_data = SDATA (bytestr); | ||
| 900 | vectorp = XVECTOR (vector)->contents; | ||
| 901 | if (BYTE_CODE_SAFE) | ||
| 902 | { | ||
| 903 | /* Only required for checking, not for execution. */ | ||
| 904 | const_length = ASIZE (vector); | ||
| 905 | bytestr_length = SCHARS (bytestr); | ||
| 906 | } | ||
| 907 | |||
| 908 | TOP = val; | ||
| 909 | NEXT; | ||
| 910 | } | ||
| 911 | else | ||
| 912 | goto exit; | ||
| 913 | } | ||
| 779 | 914 | ||
| 780 | CASE (Bdiscard): | 915 | CASE (Bdiscard): |
| 781 | DISCARD (1); | 916 | DISCARD (1); |
| @@ -789,8 +924,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 789 | record_unwind_protect_excursion (); | 924 | record_unwind_protect_excursion (); |
| 790 | NEXT; | 925 | NEXT; |
| 791 | 926 | ||
| 792 | CASE (Bsave_current_buffer): /* Obsolete since ??. */ | 927 | CASE (Bsave_current_buffer_OBSOLETE): /* Obsolete since 20. */ |
| 793 | CASE (Bsave_current_buffer_1): | 928 | CASE (Bsave_current_buffer): |
| 794 | record_unwind_current_buffer (); | 929 | record_unwind_current_buffer (); |
| 795 | NEXT; | 930 | NEXT; |
| 796 | 931 | ||
| @@ -830,9 +965,23 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 830 | if (sys_setjmp (c->jmp)) | 965 | if (sys_setjmp (c->jmp)) |
| 831 | { | 966 | { |
| 832 | struct handler *c = handlerlist; | 967 | struct handler *c = handlerlist; |
| 968 | handlerlist = c->next; | ||
| 833 | top = c->bytecode_top; | 969 | top = c->bytecode_top; |
| 834 | op = c->bytecode_dest; | 970 | op = c->bytecode_dest; |
| 835 | handlerlist = c->next; | 971 | struct bc_frame *fp = bc->fp; |
| 972 | |||
| 973 | Lisp_Object fun = fp->fun; | ||
| 974 | Lisp_Object bytestr = AREF (fun, COMPILED_BYTECODE); | ||
| 975 | Lisp_Object vector = AREF (fun, COMPILED_CONSTANTS); | ||
| 976 | bytestr_data = SDATA (bytestr); | ||
| 977 | vectorp = XVECTOR (vector)->contents; | ||
| 978 | if (BYTE_CODE_SAFE) | ||
| 979 | { | ||
| 980 | /* Only required for checking, not for execution. */ | ||
| 981 | const_length = ASIZE (vector); | ||
| 982 | bytestr_length = SCHARS (bytestr); | ||
| 983 | } | ||
| 984 | pc = bytestr_data; | ||
| 836 | PUSH (c->val); | 985 | PUSH (c->val); |
| 837 | goto op_branch; | 986 | goto op_branch; |
| 838 | } | 987 | } |
| @@ -1060,7 +1209,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 1060 | Lisp_Object v2 = POP; | 1209 | Lisp_Object v2 = POP; |
| 1061 | Lisp_Object v1 = TOP; | 1210 | Lisp_Object v1 = TOP; |
| 1062 | if (FIXNUMP (v1) && FIXNUMP (v2)) | 1211 | if (FIXNUMP (v1) && FIXNUMP (v2)) |
| 1063 | TOP = BASE_EQ(v1, v2) ? Qt : Qnil; | 1212 | TOP = BASE_EQ (v1, v2) ? Qt : Qnil; |
| 1064 | else | 1213 | else |
| 1065 | TOP = arithcompare (v1, v2, ARITH_EQUAL); | 1214 | TOP = arithcompare (v1, v2, ARITH_EQUAL); |
| 1066 | NEXT; | 1215 | NEXT; |
| @@ -1331,8 +1480,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 1331 | 1480 | ||
| 1332 | CASE (Bnarrow_to_region): | 1481 | CASE (Bnarrow_to_region): |
| 1333 | { | 1482 | { |
| 1334 | Lisp_Object v1 = POP; | 1483 | Lisp_Object v2 = POP, v1 = POP; |
| 1335 | TOP = Fnarrow_to_region (TOP, v1); | 1484 | TOP = Fnarrow_to_region (TOP, v1, v2); |
| 1336 | NEXT; | 1485 | NEXT; |
| 1337 | } | 1486 | } |
| 1338 | 1487 | ||
| @@ -1471,19 +1620,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 1471 | TOP = INTEGERP (TOP) ? Qt : Qnil; | 1620 | TOP = INTEGERP (TOP) ? Qt : Qnil; |
| 1472 | NEXT; | 1621 | NEXT; |
| 1473 | 1622 | ||
| 1474 | #if BYTE_CODE_SAFE | ||
| 1475 | /* These are intentionally written using 'case' syntax, | ||
| 1476 | because they are incompatible with the threaded | ||
| 1477 | interpreter. */ | ||
| 1478 | |||
| 1479 | case Bset_mark: | ||
| 1480 | error ("set-mark is an obsolete bytecode"); | ||
| 1481 | break; | ||
| 1482 | case Bscan_buffer: | ||
| 1483 | error ("scan-buffer is an obsolete bytecode"); | ||
| 1484 | break; | ||
| 1485 | #endif | ||
| 1486 | |||
| 1487 | CASE_ABORT: | 1623 | CASE_ABORT: |
| 1488 | /* Actually this is Bstack_ref with offset 0, but we use Bdup | 1624 | /* Actually this is Bstack_ref with offset 0, but we use Bdup |
| 1489 | for that instead. */ | 1625 | for that instead. */ |
| @@ -1542,6 +1678,12 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 1542 | /* TODO: Perhaps introduce another byte-code for switch when the | 1678 | /* TODO: Perhaps introduce another byte-code for switch when the |
| 1543 | number of cases is less, which uses a simple vector for linear | 1679 | number of cases is less, which uses a simple vector for linear |
| 1544 | search as the jump table. */ | 1680 | search as the jump table. */ |
| 1681 | |||
| 1682 | /* TODO: Instead of pushing the table in a separate | ||
| 1683 | Bconstant op, use an immediate argument (maybe separate | ||
| 1684 | switch opcodes for 1-byte and 2-byte constant indices). | ||
| 1685 | This would also get rid of some hacks that assume each | ||
| 1686 | Bswitch to be preceded by a Bconstant. */ | ||
| 1545 | Lisp_Object jmp_table = POP; | 1687 | Lisp_Object jmp_table = POP; |
| 1546 | if (BYTE_CODE_SAFE && !HASH_TABLE_P (jmp_table)) | 1688 | if (BYTE_CODE_SAFE && !HASH_TABLE_P (jmp_table)) |
| 1547 | emacs_abort (); | 1689 | emacs_abort (); |
| @@ -1584,20 +1726,9 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 1584 | 1726 | ||
| 1585 | exit: | 1727 | exit: |
| 1586 | 1728 | ||
| 1587 | #if BYTE_CODE_SAFE || !defined NDEBUG | 1729 | bc->fp = bc->fp->saved_fp; |
| 1588 | if (!specpdl_ref_eq (SPECPDL_INDEX (), count)) | ||
| 1589 | { | ||
| 1590 | /* Binds and unbinds are supposed to be compiled balanced. */ | ||
| 1591 | if (specpdl_ref_lt (count, SPECPDL_INDEX ())) | ||
| 1592 | unbind_to (count, Qnil); | ||
| 1593 | error ("binding stack not balanced (serious byte compiler bug)"); | ||
| 1594 | } | ||
| 1595 | #endif | ||
| 1596 | /* The byte code should have been properly pinned. */ | ||
| 1597 | eassert (SDATA (bytestr) == bytestr_data); | ||
| 1598 | 1730 | ||
| 1599 | Lisp_Object result = TOP; | 1731 | Lisp_Object result = TOP; |
| 1600 | SAFE_FREE (); | ||
| 1601 | return result; | 1732 | return result; |
| 1602 | } | 1733 | } |
| 1603 | 1734 | ||
| @@ -1619,6 +1750,7 @@ void | |||
| 1619 | syms_of_bytecode (void) | 1750 | syms_of_bytecode (void) |
| 1620 | { | 1751 | { |
| 1621 | defsubr (&Sbyte_code); | 1752 | defsubr (&Sbyte_code); |
| 1753 | defsubr (&Sinternal_stack_stats); | ||
| 1622 | 1754 | ||
| 1623 | #ifdef BYTE_CODE_METER | 1755 | #ifdef BYTE_CODE_METER |
| 1624 | 1756 | ||