aboutsummaryrefslogtreecommitdiffstats
path: root/src/bytecode.c
diff options
context:
space:
mode:
authorAlan Mackenzie2016-12-23 20:28:21 +0000
committerAlan Mackenzie2016-12-23 20:28:21 +0000
commit441e3b78c7b4a874e98bbc436f2b8d9771ca9d4e (patch)
treedcad6019cc15c5bc39eb0385e5c54f4170d07d23 /src/bytecode.c
parentde077da39da7d143f904d6405b62919e5f3e72d6 (diff)
parenteff901b8a39f42ddedf4c1db833b9071cae5962f (diff)
downloademacs-441e3b78c7b4a874e98bbc436f2b8d9771ca9d4e.tar.gz
emacs-441e3b78c7b4a874e98bbc436f2b8d9771ca9d4e.zip
Merge branch 'master' into comment-cache
Diffstat (limited to 'src/bytecode.c')
-rw-r--r--src/bytecode.c203
1 files changed, 155 insertions, 48 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index 71ecdbf2cc0..c581ed6d982 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -280,10 +280,68 @@ enum byte_code_op
280 Bset_mark = 0163, /* this loser is no longer generated as of v18 */ 280 Bset_mark = 0163, /* this loser is no longer generated as of v18 */
281#endif 281#endif
282}; 282};
283
284/* Whether to maintain a `top' and `bottom' field in the stack frame. */
285#define BYTE_MAINTAIN_TOP BYTE_CODE_SAFE
283 286
284/* Fetch the next byte from the bytecode stream. */ 287/* Structure describing a value stack used during byte-code execution
288 in Fbyte_code. */
289
290struct byte_stack
291{
292 /* Program counter. This points into the byte_string below
293 and is relocated when that string is relocated. */
294 const unsigned char *pc;
295
296 /* Top and bottom of stack. The bottom points to an area of memory
297 allocated with alloca in Fbyte_code. */
298#if BYTE_MAINTAIN_TOP
299 Lisp_Object *top, *bottom;
300#endif
301
302 /* The string containing the byte-code, and its current address.
303 Storing this here protects it from GC because mark_byte_stack
304 marks it. */
305 Lisp_Object byte_string;
306 const unsigned char *byte_string_start;
307
308 /* Next entry in byte_stack_list. */
309 struct byte_stack *next;
310};
311
312/* A list of currently active byte-code execution value stacks.
313 Fbyte_code adds an entry to the head of this list before it starts
314 processing byte-code, and it removes the entry again when it is
315 done. Signaling an error truncates the list.
316
317 byte_stack_list is a macro defined in thread.h. */
318/* struct byte_stack *byte_stack_list; */
319
320
321/* Relocate program counters in the stacks on byte_stack_list. Called
322 when GC has completed. */
323
324void
325relocate_byte_stack (struct byte_stack *stack)
326{
327 for (; stack; stack = stack->next)
328 {
329 if (stack->byte_string_start != SDATA (stack->byte_string))
330 {
331 ptrdiff_t offset = stack->pc - stack->byte_string_start;
332 stack->byte_string_start = SDATA (stack->byte_string);
333 stack->pc = stack->byte_string_start + offset;
334 }
335 }
336}
285 337
286#define FETCH (*pc++) 338
339/* Fetch the next byte from the bytecode stream. */
340#ifdef BYTE_CODE_SAFE
341#define FETCH (eassert (stack.byte_string_start == SDATA (stack.byte_string)), *stack.pc++)
342#else
343#define FETCH *stack.pc++
344#endif
287 345
288/* Fetch two bytes from the bytecode stream and make a 16-bit number 346/* Fetch two bytes from the bytecode stream and make a 16-bit number
289 out of them. */ 347 out of them. */
@@ -308,6 +366,29 @@ enum byte_code_op
308 366
309#define TOP (*top) 367#define TOP (*top)
310 368
369#define CHECK_RANGE(ARG) \
370 (BYTE_CODE_SAFE && bytestr_length <= (ARG) ? emacs_abort () : (void) 0)
371
372/* A version of the QUIT macro which makes sure that the stack top is
373 set before signaling `quit'. */
374#define BYTE_CODE_QUIT \
375 do { \
376 if (quitcounter++) \
377 break; \
378 maybe_gc (); \
379 if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \
380 { \
381 Lisp_Object flag = Vquit_flag; \
382 Vquit_flag = Qnil; \
383 if (EQ (Vthrow_on_input, flag)) \
384 Fthrow (Vthrow_on_input, Qt); \
385 quit (); \
386 } \
387 else if (pending_signals) \
388 process_pending_signals (); \
389 } while (0)
390
391
311DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0, 392DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0,
312 doc: /* Function used internally in byte-compiled code. 393 doc: /* Function used internally in byte-compiled code.
313The first argument, BYTESTR, is a string of byte code; 394The first argument, BYTESTR, is a string of byte code;
@@ -357,18 +438,19 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
357 438
358 ptrdiff_t bytestr_length = SBYTES (bytestr); 439 ptrdiff_t bytestr_length = SBYTES (bytestr);
359 Lisp_Object *vectorp = XVECTOR (vector)->contents; 440 Lisp_Object *vectorp = XVECTOR (vector)->contents;
441 struct byte_stack stack;
360 442
361 unsigned char quitcounter = 1; 443 stack.byte_string = bytestr;
444 stack.pc = stack.byte_string_start = SDATA (bytestr);
445 unsigned char quitcounter = 0;
362 EMACS_INT stack_items = XFASTINT (maxdepth) + 1; 446 EMACS_INT stack_items = XFASTINT (maxdepth) + 1;
363 USE_SAFE_ALLOCA; 447 USE_SAFE_ALLOCA;
364 Lisp_Object *stack_base; 448 Lisp_Object *stack_base;
365 SAFE_ALLOCA_LISP_EXTRA (stack_base, stack_items, bytestr_length); 449 SAFE_ALLOCA_LISP (stack_base, stack_items);
366 Lisp_Object *stack_lim = stack_base + stack_items; 450 Lisp_Object *stack_lim = stack_base + stack_items;
367 Lisp_Object *top = stack_base; 451 Lisp_Object *top = stack_base;
368 memcpy (stack_lim, SDATA (bytestr), bytestr_length); 452 stack.next = byte_stack_list;
369 void *void_stack_lim = stack_lim; 453 byte_stack_list = &stack;
370 unsigned char const *bytestr_data = void_stack_lim;
371 unsigned char const *pc = bytestr_data;
372 ptrdiff_t count = SPECPDL_INDEX (); 454 ptrdiff_t count = SPECPDL_INDEX ();
373 455
374 if (!NILP (args_template)) 456 if (!NILP (args_template))
@@ -508,10 +590,15 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
508 590
509 CASE (Bgotoifnil): 591 CASE (Bgotoifnil):
510 { 592 {
511 Lisp_Object v1 = POP; 593 Lisp_Object v1;
512 op = FETCH2; 594 op = FETCH2;
595 v1 = POP;
513 if (NILP (v1)) 596 if (NILP (v1))
514 goto op_branch; 597 {
598 BYTE_CODE_QUIT;
599 CHECK_RANGE (op);
600 stack.pc = stack.byte_string_start + op;
601 }
515 NEXT; 602 NEXT;
516 } 603 }
517 604
@@ -569,7 +656,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
569 if (SYMBOLP (sym) 656 if (SYMBOLP (sym)
570 && !EQ (val, Qunbound) 657 && !EQ (val, Qunbound)
571 && !XSYMBOL (sym)->redirect 658 && !XSYMBOL (sym)->redirect
572 && !SYMBOL_TRAPPED_WRITE_P (sym)) 659 && !SYMBOL_TRAPPED_WRITE_P (sym))
573 SET_SYMBOL_VAL (XSYMBOL (sym), val); 660 SET_SYMBOL_VAL (XSYMBOL (sym), val);
574 else 661 else
575 set_internal (sym, val, Qnil, SET_INTERNAL_SET); 662 set_internal (sym, val, Qnil, SET_INTERNAL_SET);
@@ -666,72 +753,86 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
666 NEXT; 753 NEXT;
667 754
668 CASE (Bgoto): 755 CASE (Bgoto):
669 op = FETCH2; 756 BYTE_CODE_QUIT;
670 op_branch: 757 op = FETCH2; /* pc = FETCH2 loses since FETCH2 contains pc++ */
671 op -= pc - bytestr_data; 758 CHECK_RANGE (op);
672 op_relative_branch: 759 stack.pc = stack.byte_string_start + op;
673 if (BYTE_CODE_SAFE
674 && ! (bytestr_data - pc <= op
675 && op < bytestr_data + bytestr_length - pc))
676 emacs_abort ();
677 quitcounter += op < 0;
678 if (!quitcounter)
679 {
680 quitcounter = 1;
681 maybe_gc ();
682 QUIT;
683 }
684 pc += op;
685 NEXT; 760 NEXT;
686 761
687 CASE (Bgotoifnonnil): 762 CASE (Bgotoifnonnil):
688 op = FETCH2; 763 op = FETCH2;
689 if (!NILP (POP)) 764 Lisp_Object v1 = POP;
690 goto op_branch; 765 if (!NILP (v1))
766 {
767 BYTE_CODE_QUIT;
768 CHECK_RANGE (op);
769 stack.pc = stack.byte_string_start + op;
770 }
691 NEXT; 771 NEXT;
692 772
693 CASE (Bgotoifnilelsepop): 773 CASE (Bgotoifnilelsepop):
694 op = FETCH2; 774 op = FETCH2;
695 if (NILP (TOP)) 775 if (NILP (TOP))
696 goto op_branch; 776 {
697 DISCARD (1); 777 BYTE_CODE_QUIT;
778 CHECK_RANGE (op);
779 stack.pc = stack.byte_string_start + op;
780 }
781 else DISCARD (1);
698 NEXT; 782 NEXT;
699 783
700 CASE (Bgotoifnonnilelsepop): 784 CASE (Bgotoifnonnilelsepop):
701 op = FETCH2; 785 op = FETCH2;
702 if (!NILP (TOP)) 786 if (!NILP (TOP))
703 goto op_branch; 787 {
704 DISCARD (1); 788 BYTE_CODE_QUIT;
789 CHECK_RANGE (op);
790 stack.pc = stack.byte_string_start + op;
791 }
792 else DISCARD (1);
705 NEXT; 793 NEXT;
706 794
707 CASE (BRgoto): 795 CASE (BRgoto):
708 op = FETCH - 128; 796 BYTE_CODE_QUIT;
709 goto op_relative_branch; 797 stack.pc += (int) *stack.pc - 127;
798 NEXT;
710 799
711 CASE (BRgotoifnil): 800 CASE (BRgotoifnil):
712 op = FETCH - 128;
713 if (NILP (POP)) 801 if (NILP (POP))
714 goto op_relative_branch; 802 {
803 BYTE_CODE_QUIT;
804 stack.pc += (int) *stack.pc - 128;
805 }
806 stack.pc++;
715 NEXT; 807 NEXT;
716 808
717 CASE (BRgotoifnonnil): 809 CASE (BRgotoifnonnil):
718 op = FETCH - 128;
719 if (!NILP (POP)) 810 if (!NILP (POP))
720 goto op_relative_branch; 811 {
812 BYTE_CODE_QUIT;
813 stack.pc += (int) *stack.pc - 128;
814 }
815 stack.pc++;
721 NEXT; 816 NEXT;
722 817
723 CASE (BRgotoifnilelsepop): 818 CASE (BRgotoifnilelsepop):
724 op = FETCH - 128; 819 op = *stack.pc++;
725 if (NILP (TOP)) 820 if (NILP (TOP))
726 goto op_relative_branch; 821 {
727 DISCARD (1); 822 BYTE_CODE_QUIT;
823 stack.pc += op - 128;
824 }
825 else DISCARD (1);
728 NEXT; 826 NEXT;
729 827
730 CASE (BRgotoifnonnilelsepop): 828 CASE (BRgotoifnonnilelsepop):
731 op = FETCH - 128; 829 op = *stack.pc++;
732 if (!NILP (TOP)) 830 if (!NILP (TOP))
733 goto op_relative_branch; 831 {
734 DISCARD (1); 832 BYTE_CODE_QUIT;
833 stack.pc += op - 128;
834 }
835 else DISCARD (1);
735 NEXT; 836 NEXT;
736 837
737 CASE (Breturn): 838 CASE (Breturn):
@@ -791,11 +892,15 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
791 if (sys_setjmp (c->jmp)) 892 if (sys_setjmp (c->jmp))
792 { 893 {
793 struct handler *c = handlerlist; 894 struct handler *c = handlerlist;
895 int dest;
794 top = c->bytecode_top; 896 top = c->bytecode_top;
795 op = c->bytecode_dest; 897 dest = c->bytecode_dest;
796 handlerlist = c->next; 898 handlerlist = c->next;
797 PUSH (c->val); 899 PUSH (c->val);
798 goto op_branch; 900 CHECK_RANGE (dest);
901 /* Might have been re-set by longjmp! */
902 stack.byte_string_start = SDATA (stack.byte_string);
903 stack.pc = stack.byte_string_start + dest;
799 } 904 }
800 905
801 NEXT; 906 NEXT;
@@ -1363,7 +1468,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1363 call3 (Qerror, 1468 call3 (Qerror,
1364 build_string ("Invalid byte opcode: op=%s, ptr=%d"), 1469 build_string ("Invalid byte opcode: op=%s, ptr=%d"),
1365 make_number (op), 1470 make_number (op),
1366 make_number (pc - 1 - bytestr_data)); 1471 make_number (stack.pc - 1 - stack.byte_string_start));
1367 1472
1368 /* Handy byte-codes for lexical binding. */ 1473 /* Handy byte-codes for lexical binding. */
1369 CASE (Bstack_ref1): 1474 CASE (Bstack_ref1):
@@ -1423,6 +1528,8 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1423 1528
1424 exit: 1529 exit:
1425 1530
1531 byte_stack_list = byte_stack_list->next;
1532
1426 /* Binds and unbinds are supposed to be compiled balanced. */ 1533 /* Binds and unbinds are supposed to be compiled balanced. */
1427 if (SPECPDL_INDEX () != count) 1534 if (SPECPDL_INDEX () != count)
1428 { 1535 {