comparison src/bytecode.c @ 435:43e88c4db330

*** empty log message ***
author Richard M. Stallman <rms@gnu.org>
date Tue, 26 Nov 1991 05:00:30 +0000
parents d0eb77a4d8f7
children db84d8d9a1d9
comparison
equal deleted inserted replaced
434:ab8836c672bd 435:43e88c4db330
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19 19
20 hacked on by jwz@lucid.com 17-jun-91 20 hacked on by jwz@lucid.com 17-jun-91
21 o added a compile-time switch to turn on simple sanity checking; 21 o added a compile-time switch to turn on simple sanity checking;
22 o put back the obsolete byte-codes for error-detection; 22 o put back the obsolete byte-codes for error-detection;
23 o put back fset, symbol-function, and read-char because I don't
24 see any reason for them to have been removed;
25 o added a new instruction, unbind_all, which I will use for 23 o added a new instruction, unbind_all, which I will use for
26 tail-recursion elimination; 24 tail-recursion elimination;
27 o made temp_output_buffer_show() be called with the right number 25 o made temp_output_buffer_show be called with the right number
28 of args; 26 of args;
29 o made the new bytecodes be called with args in the right order; 27 o made the new bytecodes be called with args in the right order;
30 o added metering support. 28 o added metering support.
31 29
32 by Hallvard: 30 by Hallvard:
33 o added relative jump instructions. 31 o added relative jump instructions;
34 o all conditionals now only do QUIT if they jump. 32 o all conditionals now only do QUIT if they jump.
35 */ 33 */
36
37 34
38 #include "config.h" 35 #include "config.h"
39 #include "lisp.h" 36 #include "lisp.h"
40 #include "buffer.h" 37 #include "buffer.h"
41 #include "syntax.h" 38 #include "syntax.h"
44 * define BYTE_CODE_SAFE to enable some minor sanity checking (useful for 41 * define BYTE_CODE_SAFE to enable some minor sanity checking (useful for
45 * debugging the byte compiler...) 42 * debugging the byte compiler...)
46 * 43 *
47 * define BYTE_CODE_METER to enable generation of a byte-op usage histogram. 44 * define BYTE_CODE_METER to enable generation of a byte-op usage histogram.
48 */ 45 */
49 #define BYTE_CODE_SAFE 46 /* #define BYTE_CODE_SAFE */
50 #define BYTE_CODE_METER 47 /* #define BYTE_CODE_METER */
51 48
52 49
53 #ifdef BYTE_CODE_METER 50 #ifdef BYTE_CODE_METER
54 51
55 Lisp_Object Vbyte_code_meter, Qbyte_code_meter; 52 Lisp_Object Vbyte_code_meter, Qbyte_code_meter;
56 int byte_metering_on; 53 int byte_metering_on;
57 54
58 # define METER_2(code1,code2) \ 55 #define METER_2(code1, code2) \
59 XFASTINT (XVECTOR (XVECTOR (Vbyte_code_meter)->contents[(code1)]) \ 56 XFASTINT (XVECTOR (XVECTOR (Vbyte_code_meter)->contents[(code1)]) \
60 ->contents[(code2)]) 57 ->contents[(code2)])
61 58
62 # define METER_1(code) METER_2 (0,(code)) 59 #define METER_1(code) METER_2 (0, (code))
63 60
64 # define METER_CODE(last_code, this_code) { \ 61 #define METER_CODE(last_code, this_code) \
65 if (byte_metering_on) { \ 62 { \
66 if (METER_1 (this_code) != ((1<<VALBITS)-1)) \ 63 if (byte_metering_on) \
67 METER_1 (this_code) ++; \ 64 { \
68 if (last_code && \ 65 if (METER_1 (this_code) != ((1<<VALBITS)-1)) \
69 METER_2 (last_code,this_code) != ((1<<VALBITS)-1)) \ 66 METER_1 (this_code)++; \
70 METER_2 (last_code,this_code) ++; \ 67 if (last_code \
71 } \ 68 && METER_2 (last_code, this_code) != ((1<<VALBITS)-1)) \
72 } 69 METER_2 (last_code, this_code)++; \
73 70 } \
74 #else /* ! BYTE_CODE_METER */ 71 }
75 72
76 # define meter_code(last_code, this_code) 73 #else /* no BYTE_CODE_METER */
77 74
78 #endif 75 #define METER_CODE(last_code, this_code)
76
77 #endif /* no BYTE_CODE_METER */
79 78
80 79
81 Lisp_Object Qbytecode; 80 Lisp_Object Qbytecode;
82 81
83 /* Byte codes: */ 82 /* Byte codes: */
105 #define Blist4 0106 104 #define Blist4 0106
106 #define Blength 0107 105 #define Blength 0107
107 #define Baref 0110 106 #define Baref 0110
108 #define Baset 0111 107 #define Baset 0111
109 #define Bsymbol_value 0112 108 #define Bsymbol_value 0112
110 #define Bsymbol_function 0113 109 #define Bsymbol_function 0113 /* no longer generated as of v19 */
111 #define Bset 0114 110 #define Bset 0114
112 #define Bfset 0115 111 #define Bfset 0115 /* no longer generated as of v19 */
113 #define Bget 0116 112 #define Bget 0116
114 #define Bsubstring 0117 113 #define Bsubstring 0117
115 #define Bconcat2 0120 114 #define Bconcat2 0120
116 #define Bconcat3 0121 115 #define Bconcat3 0121
117 #define Bconcat4 0122 116 #define Bconcat4 0122
215 #define BRgotoifnilelsepop 0255 214 #define BRgotoifnilelsepop 0255
216 #define BRgotoifnonnilelsepop 0256 215 #define BRgotoifnonnilelsepop 0256
217 216
218 #define BlistN 0257 217 #define BlistN 0257
219 #define BconcatN 0260 218 #define BconcatN 0260
219 #define BinsertN 0261
220 220
221 #define Bconstant 0300 221 #define Bconstant 0300
222 #define CONSTANTLIM 0100 222 #define CONSTANTLIM 0100
223 223
224 /* Fetch the next byte from the bytecode stream */ 224 /* Fetch the next byte from the bytecode stream */
299 299
300 while (1) 300 while (1)
301 { 301 {
302 #ifdef BYTE_CODE_SAFE 302 #ifdef BYTE_CODE_SAFE
303 if (stackp > stacke) 303 if (stackp > stacke)
304 error ( 304 error ("Byte code stack overflow (byte compiler bug), pc %d, depth %d",
305 "Stack overflow in byte code (byte compiler bug), pc = %d, depth = %d",
306 pc - XSTRING (string_saved)->data, stacke - stackp); 305 pc - XSTRING (string_saved)->data, stacke - stackp);
307 if (stackp < stack) 306 if (stackp < stack)
308 error ("Stack underflow in byte code (byte compiler bug), pc = %d", 307 error ("Byte code stack underflow (byte compiler bug), pc %d",
309 pc - XSTRING (string_saved)->data); 308 pc - XSTRING (string_saved)->data);
310 #endif 309 #endif
311 310
312 if (string_saved != bytestr) 311 if (string_saved != bytestr)
313 { 312 {
404 403
405 case Bcall: case Bcall+1: case Bcall+2: case Bcall+3: 404 case Bcall: case Bcall+1: case Bcall+2: case Bcall+3:
406 case Bcall+4: case Bcall+5: 405 case Bcall+4: case Bcall+5:
407 op -= Bcall; 406 op -= Bcall;
408 docall: 407 docall:
409 DISCARD(op); 408 DISCARD (op);
410 #ifdef BYTE_CODE_METER 409 #ifdef BYTE_CODE_METER
411 if (byte_metering_on && XTYPE (TOP) == Lisp_Symbol) 410 if (byte_metering_on && XTYPE (TOP) == Lisp_Symbol)
412 { 411 {
413 v1 = TOP; 412 v1 = TOP;
414 v2 = Fget (v1, Qbyte_code_meter); 413 v2 = Fget (v1, Qbyte_code_meter);
417 XSETINT (v2, XINT (v2) + 1); 416 XSETINT (v2, XINT (v2) + 1);
418 Fput (v1, Qbyte_code_meter, v2); 417 Fput (v1, Qbyte_code_meter, v2);
419 } 418 }
420 } 419 }
421 #endif 420 #endif
421 /* The frobbing of gcpro3 was lost by jwz's changes in June 91
422 and then reinserted by jwz in Nov 91. */
423 /* Remove protection from the args we are giving to Ffuncall.
424 FFuncall will protect them, and double protection would
425 cause disasters. */
426 gcpro3.nvars = &TOP - stack - 1;
422 TOP = Ffuncall (op + 1, &TOP); 427 TOP = Ffuncall (op + 1, &TOP);
428 gcpro3.nvars = XFASTINT (maxdepth);
423 break; 429 break;
424 430
425 case Bunbind+6: 431 case Bunbind+6:
426 op = FETCH; 432 op = FETCH;
427 goto dounbind; 433 goto dounbind;
437 unbind_to (specpdl_ptr - specpdl - op, Qnil); 443 unbind_to (specpdl_ptr - specpdl - op, Qnil);
438 break; 444 break;
439 445
440 case Bunbind_all: 446 case Bunbind_all:
441 /* To unbind back to the beginning of this frame. Not used yet, 447 /* To unbind back to the beginning of this frame. Not used yet,
442 but wil be needed for tail-recursion elimination. 448 but will be needed for tail-recursion elimination. */
443 */
444 unbind_to (count, Qnil); 449 unbind_to (count, Qnil);
445 break; 450 break;
446 451
447 case Bgoto: 452 case Bgoto:
448 QUIT; 453 QUIT;
473 if (NULL (TOP)) 478 if (NULL (TOP))
474 { 479 {
475 QUIT; 480 QUIT;
476 pc = XSTRING (string_saved)->data + op; 481 pc = XSTRING (string_saved)->data + op;
477 } 482 }
478 else DISCARD(1); 483 else DISCARD (1);
479 break; 484 break;
480 485
481 case Bgotoifnonnilelsepop: 486 case Bgotoifnonnilelsepop:
482 op = FETCH2; 487 op = FETCH2;
483 if (!NULL (TOP)) 488 if (!NULL (TOP))
484 { 489 {
485 QUIT; 490 QUIT;
486 pc = XSTRING (string_saved)->data + op; 491 pc = XSTRING (string_saved)->data + op;
487 } 492 }
488 else DISCARD(1); 493 else DISCARD (1);
489 break; 494 break;
490 495
491 case BRgoto: 496 case BRgoto:
492 QUIT; 497 QUIT;
493 pc += *pc - 127; 498 pc += *pc - 127;
516 if (NULL (TOP)) 521 if (NULL (TOP))
517 { 522 {
518 QUIT; 523 QUIT;
519 pc += op - 128; 524 pc += op - 128;
520 } 525 }
521 else DISCARD(1); 526 else DISCARD (1);
522 break; 527 break;
523 528
524 case BRgotoifnonnilelsepop: 529 case BRgotoifnonnilelsepop:
525 op = *pc++; 530 op = *pc++;
526 if (!NULL (TOP)) 531 if (!NULL (TOP))
527 { 532 {
528 QUIT; 533 QUIT;
529 pc += op - 128; 534 pc += op - 128;
530 } 535 }
531 else DISCARD(1); 536 else DISCARD (1);
532 break; 537 break;
533 538
534 case Breturn: 539 case Breturn:
535 v1 = POP; 540 v1 = POP;
536 goto exit; 541 goto exit;
537 542
538 case Bdiscard: 543 case Bdiscard:
539 DISCARD(1); 544 DISCARD (1);
540 break; 545 break;
541 546
542 case Bdup: 547 case Bdup:
543 v1 = TOP; 548 v1 = TOP;
544 PUSH (v1); 549 PUSH (v1);
669 v1 = POP; 674 v1 = POP;
670 TOP = Fcons (TOP, Fcons (v1, Qnil)); 675 TOP = Fcons (TOP, Fcons (v1, Qnil));
671 break; 676 break;
672 677
673 case Blist3: 678 case Blist3:
674 DISCARD(2); 679 DISCARD (2);
675 TOP = Flist (3, &TOP); 680 TOP = Flist (3, &TOP);
676 break; 681 break;
677 682
678 case Blist4: 683 case Blist4:
679 DISCARD(3); 684 DISCARD (3);
680 TOP = Flist (4, &TOP); 685 TOP = Flist (4, &TOP);
681 break; 686 break;
682 687
683 case BlistN: 688 case BlistN:
684 op = FETCH; 689 op = FETCH;
727 v2 = POP; v1 = POP; 732 v2 = POP; v1 = POP;
728 TOP = Fsubstring (TOP, v1, v2); 733 TOP = Fsubstring (TOP, v1, v2);
729 break; 734 break;
730 735
731 case Bconcat2: 736 case Bconcat2:
732 DISCARD(1); 737 DISCARD (1);
733 TOP = Fconcat (2, &TOP); 738 TOP = Fconcat (2, &TOP);
734 break; 739 break;
735 740
736 case Bconcat3: 741 case Bconcat3:
737 DISCARD(2); 742 DISCARD (2);
738 TOP = Fconcat (3, &TOP); 743 TOP = Fconcat (3, &TOP);
739 break; 744 break;
740 745
741 case Bconcat4: 746 case Bconcat4:
742 DISCARD(3); 747 DISCARD (3);
743 TOP = Fconcat (4, &TOP); 748 TOP = Fconcat (4, &TOP);
744 break; 749 break;
745 750
746 case BconcatN: 751 case BconcatN:
747 op = FETCH; 752 op = FETCH;
797 v1 = POP; 802 v1 = POP;
798 TOP = Fgeq (TOP, v1); 803 TOP = Fgeq (TOP, v1);
799 break; 804 break;
800 805
801 case Bdiff: 806 case Bdiff:
802 DISCARD(1); 807 DISCARD (1);
803 TOP = Fminus (2, &TOP); 808 TOP = Fminus (2, &TOP);
804 break; 809 break;
805 810
806 case Bnegate: 811 case Bnegate:
807 v1 = TOP; 812 v1 = TOP;
813 else 818 else
814 TOP = Fminus (1, &TOP); 819 TOP = Fminus (1, &TOP);
815 break; 820 break;
816 821
817 case Bplus: 822 case Bplus:
818 DISCARD(1); 823 DISCARD (1);
819 TOP = Fplus (2, &TOP); 824 TOP = Fplus (2, &TOP);
820 break; 825 break;
821 826
822 case Bmax: 827 case Bmax:
823 DISCARD(1); 828 DISCARD (1);
824 TOP = Fmax (2, &TOP); 829 TOP = Fmax (2, &TOP);
825 break; 830 break;
826 831
827 case Bmin: 832 case Bmin:
828 DISCARD(1); 833 DISCARD (1);
829 TOP = Fmin (2, &TOP); 834 TOP = Fmin (2, &TOP);
830 break; 835 break;
831 836
832 case Bmult: 837 case Bmult:
833 DISCARD(1); 838 DISCARD (1);
834 TOP = Ftimes (2, &TOP); 839 TOP = Ftimes (2, &TOP);
835 break; 840 break;
836 841
837 case Bquo: 842 case Bquo:
838 DISCARD(1); 843 DISCARD (1);
839 TOP = Fquo (2, &TOP); 844 TOP = Fquo (2, &TOP);
840 break; 845 break;
841 846
842 case Brem: 847 case Brem:
843 v1 = POP; 848 v1 = POP;
853 TOP = Fgoto_char (TOP); 858 TOP = Fgoto_char (TOP);
854 break; 859 break;
855 860
856 case Binsert: 861 case Binsert:
857 TOP = Finsert (1, &TOP); 862 TOP = Finsert (1, &TOP);
863 break;
864
865 case BinsertN:
866 op = FETCH;
867 DISCARD (op - 1);
868 TOP = Finsert (op, &TOP);
858 break; 869 break;
859 870
860 case Bpoint_max: 871 case Bpoint_max:
861 XFASTINT (v1) = ZV; 872 XFASTINT (v1) = ZV;
862 PUSH (v1); 873 PUSH (v1);
1066 else 1077 else
1067 TOP = Qnil; 1078 TOP = Qnil;
1068 break; 1079 break;
1069 1080
1070 case Bnconc: 1081 case Bnconc:
1071 DISCARD(1); 1082 DISCARD (1);
1072 TOP = Fnconc (2, &TOP); 1083 TOP = Fnconc (2, &TOP);
1073 break; 1084 break;
1074 1085
1075 case Bnumberp: 1086 case Bnumberp:
1076 TOP = (XTYPE (TOP) == Lisp_Int || XTYPE (TOP) == Lisp_Float 1087 TOP = (XTYPE (TOP) == Lisp_Int || XTYPE (TOP) == Lisp_Float
1087 break; 1098 break;
1088 case Bscan_buffer: 1099 case Bscan_buffer:
1089 error ("scan-buffer is an obsolete bytecode"); 1100 error ("scan-buffer is an obsolete bytecode");
1090 break; 1101 break;
1091 case Bmark: 1102 case Bmark:
1092 error("mark is an obsolete bytecode"); 1103 error ("mark is an obsolete bytecode");
1093 break; 1104 break;
1094 #endif 1105 #endif
1095 1106
1096 default: 1107 default:
1097 #ifdef BYTE_CODE_SAFE 1108 #ifdef BYTE_CODE_SAFE
1126 defsubr (&Sbyte_code); 1137 defsubr (&Sbyte_code);
1127 1138
1128 #ifdef BYTE_CODE_METER 1139 #ifdef BYTE_CODE_METER
1129 1140
1130 DEFVAR_LISP ("byte-code-meter", &Vbyte_code_meter, 1141 DEFVAR_LISP ("byte-code-meter", &Vbyte_code_meter,
1131 "a vector of vectors which holds a histogram of byte-code usage."); 1142 "A vector of vectors which holds a histogram of byte-code usage.");
1132 DEFVAR_BOOL ("byte-metering-on", &byte_metering_on, ""); 1143 DEFVAR_BOOL ("byte-metering-on", &byte_metering_on, "");
1133 1144
1134 byte_metering_on = 0; 1145 byte_metering_on = 0;
1135 Vbyte_code_meter = Fmake_vector(make_number(256), make_number(0)); 1146 Vbyte_code_meter = Fmake_vector (make_number (256), make_number (0));
1147 Qbyte_code_meter = intern ("byte-code-meter");
1136 staticpro (&Qbyte_code_meter); 1148 staticpro (&Qbyte_code_meter);
1137 { 1149 {
1138 int i = 256; 1150 int i = 256;
1139 while (i--) 1151 while (i--)
1140 XVECTOR(Vbyte_code_meter)->contents[i] = 1152 XVECTOR (Vbyte_code_meter)->contents[i] =
1141 Fmake_vector(make_number(256), make_number(0)); 1153 Fmake_vector (make_number (256), make_number (0));
1142 } 1154 }
1143 #endif 1155 #endif
1144 } 1156 }