comparison src/bytecode.c @ 5118:e0db3c197671 ben-lisp-object

merge up to latest default branch, doesn't compile yet
author Ben Wing <ben@xemacs.org>
date Sat, 26 Dec 2009 21:18:49 -0600
parents 3742ea8250b5 1d61580e0cf7
children 623d57b7fbe8
comparison
equal deleted inserted replaced
5117:3742ea8250b5 5118:e0db3c197671
55 #include "buffer.h" 55 #include "buffer.h"
56 #include "bytecode.h" 56 #include "bytecode.h"
57 #include "opaque.h" 57 #include "opaque.h"
58 #include "syntax.h" 58 #include "syntax.h"
59 #include "window.h" 59 #include "window.h"
60
61 #ifdef NEW_GC
62 static Lisp_Object
63 make_compiled_function_args (int totalargs)
64 {
65 Lisp_Compiled_Function_Args *args;
66 args = XCOMPILED_FUNCTION_ARGS
67 (alloc_sized_lrecord
68 (FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Compiled_Function_Args,
69 Lisp_Object, args, totalargs),
70 &lrecord_compiled_function_args));
71 args->size = totalargs;
72 return wrap_compiled_function_args (args);
73 }
74
75 static Bytecount
76 size_compiled_function_args (const void *lheader)
77 {
78 return FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Compiled_Function_Args,
79 Lisp_Object, args,
80 ((Lisp_Compiled_Function_Args *)
81 lheader)->size);
82 }
83
84 static const struct memory_description compiled_function_args_description[] = {
85 { XD_LONG, offsetof (Lisp_Compiled_Function_Args, size) },
86 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Compiled_Function_Args, args),
87 XD_INDIRECT(0, 0) },
88 { XD_END }
89 };
90
91 DEFINE_DUMPABLE_SIZABLE_INTERNAL_LISP_OBJECT ("compiled-function-args",
92 compiled_function_args,
93 0,
94 compiled_function_args_description,
95 size_compiled_function_args,
96 Lisp_Compiled_Function_Args);
97 #endif /* NEW_GC */
60 98
61 EXFUN (Ffetch_bytecode, 1); 99 EXFUN (Ffetch_bytecode, 1);
62 100
63 Lisp_Object Qbyte_code, Qcompiled_functionp, Qinvalid_byte_code; 101 Lisp_Object Qbyte_code, Qcompiled_functionp, Qinvalid_byte_code;
64 102
202 BRgotoifnonnilelsepop = 0256, 240 BRgotoifnonnilelsepop = 0256,
203 241
204 BlistN = 0257, 242 BlistN = 0257,
205 BconcatN = 0260, 243 BconcatN = 0260,
206 BinsertN = 0261, 244 BinsertN = 0261,
245
246 Bbind_multiple_value_limits = 0262, /* New in 21.5. */
247 Bmultiple_value_list_internal = 0263, /* New in 21.5. */
248 Bmultiple_value_call = 0264, /* New in 21.5. */
249 Bthrow = 0265, /* New in 21.5. */
250
207 Bmember = 0266, /* new in v20 */ 251 Bmember = 0266, /* new in v20 */
208 Bassq = 0267, /* new in v20 */ 252 Bassq = 0267, /* new in v20 */
209 253
210 Bconstant = 0300 254 Bconstant = 0300
211 }; 255 };
254 if (BIGNUMP (obj)) BIGNUM_ARITH_RETURN (obj, neg); 298 if (BIGNUMP (obj)) BIGNUM_ARITH_RETURN (obj, neg);
255 #endif 299 #endif
256 #ifdef HAVE_RATIO 300 #ifdef HAVE_RATIO
257 if (RATIOP (obj)) RATIO_ARITH_RETURN (obj, neg); 301 if (RATIOP (obj)) RATIO_ARITH_RETURN (obj, neg);
258 #endif 302 #endif
259 #ifdef HAVE_BIG_FLOAT 303 #ifdef HAVE_BIGFLOAT
260 if (BIGFLOAT_P (obj)) BIGFLOAT_ARITH_RETURN (obj, neg); 304 if (BIGFLOATP (obj)) BIGFLOAT_ARITH_RETURN (obj, neg);
261 #endif 305 #endif
262 306
263 obj = wrong_type_argument (Qnumber_char_or_marker_p, obj); 307 obj = wrong_type_argument (Qnumber_char_or_marker_p, obj);
264 goto retry; 308 goto retry;
265 } 309 }
385 return Fcanonicalize_number (make_bignum_bg (scratch_bignum)); 429 return Fcanonicalize_number (make_bignum_bg (scratch_bignum));
386 #else 430 #else
387 ival1 *= ival2; break; 431 ival1 *= ival2; break;
388 #endif 432 #endif
389 case Bquo: 433 case Bquo:
390 if (ival2 == 0) Fsignal (Qarith_error, Qnil); 434 if (ival2 == 0)
435 signal_error_2 (Qarith_error, "division by zero", obj1, obj2);
391 ival1 /= ival2; 436 ival1 /= ival2;
392 break; 437 break;
393 case Bmax: if (ival1 < ival2) ival1 = ival2; break; 438 case Bmax: if (ival1 < ival2) ival1 = ival2; break;
394 case Bmin: if (ival1 > ival2) ival1 = ival2; break; 439 case Bmin: if (ival1 > ival2) ival1 = ival2; break;
395 } 440 }
411 bignum_mul (scratch_bignum, XBIGNUM_DATA (obj1), 456 bignum_mul (scratch_bignum, XBIGNUM_DATA (obj1),
412 XBIGNUM_DATA (obj2)); 457 XBIGNUM_DATA (obj2));
413 break; 458 break;
414 case Bquo: 459 case Bquo:
415 if (bignum_sign (XBIGNUM_DATA (obj2)) == 0) 460 if (bignum_sign (XBIGNUM_DATA (obj2)) == 0)
416 Fsignal (Qarith_error, Qnil); 461 signal_error_2 (Qarith_error, "division by zero", obj1, obj2);
417 bignum_div (scratch_bignum, XBIGNUM_DATA (obj1), 462 bignum_div (scratch_bignum, XBIGNUM_DATA (obj1),
418 XBIGNUM_DATA (obj2)); 463 XBIGNUM_DATA (obj2));
419 break; 464 break;
420 case Bmax: 465 case Bmax:
421 return bignum_gt (XBIGNUM_DATA (obj1), XBIGNUM_DATA (obj2)) 466 return bignum_gt (XBIGNUM_DATA (obj1), XBIGNUM_DATA (obj2))
439 case Bmult: 484 case Bmult:
440 ratio_mul (scratch_ratio, XRATIO_DATA (obj1), XRATIO_DATA (obj2)); 485 ratio_mul (scratch_ratio, XRATIO_DATA (obj1), XRATIO_DATA (obj2));
441 break; 486 break;
442 case Bquo: 487 case Bquo:
443 if (ratio_sign (XRATIO_DATA (obj2)) == 0) 488 if (ratio_sign (XRATIO_DATA (obj2)) == 0)
444 Fsignal (Qarith_error, Qnil); 489 signal_error_2 (Qarith_error, "division by zero", obj1, obj2);
445 ratio_div (scratch_ratio, XRATIO_DATA (obj1), XRATIO_DATA (obj2)); 490 ratio_div (scratch_ratio, XRATIO_DATA (obj1), XRATIO_DATA (obj2));
446 break; 491 break;
447 case Bmax: 492 case Bmax:
448 return ratio_gt (XRATIO_DATA (obj1), XRATIO_DATA (obj2)) 493 return ratio_gt (XRATIO_DATA (obj1), XRATIO_DATA (obj2))
449 ? obj1 : obj2; 494 ? obj1 : obj2;
471 bigfloat_mul (scratch_bigfloat, XBIGFLOAT_DATA (obj1), 516 bigfloat_mul (scratch_bigfloat, XBIGFLOAT_DATA (obj1),
472 XBIGFLOAT_DATA (obj2)); 517 XBIGFLOAT_DATA (obj2));
473 break; 518 break;
474 case Bquo: 519 case Bquo:
475 if (bigfloat_sign (XBIGFLOAT_DATA (obj2)) == 0) 520 if (bigfloat_sign (XBIGFLOAT_DATA (obj2)) == 0)
476 Fsignal (Qarith_error, Qnil); 521 signal_error_2 (Qarith_error, "division by zero", obj1, obj2);
477 bigfloat_div (scratch_bigfloat, XBIGFLOAT_DATA (obj1), 522 bigfloat_div (scratch_bigfloat, XBIGFLOAT_DATA (obj1),
478 XBIGFLOAT_DATA (obj2)); 523 XBIGFLOAT_DATA (obj2));
479 break; 524 break;
480 case Bmax: 525 case Bmax:
481 return bigfloat_gt (XBIGFLOAT_DATA (obj1), XBIGFLOAT_DATA (obj2)) 526 return bigfloat_gt (XBIGFLOAT_DATA (obj1), XBIGFLOAT_DATA (obj2))
493 { 538 {
494 case Bplus: dval1 += dval2; break; 539 case Bplus: dval1 += dval2; break;
495 case Bdiff: dval1 -= dval2; break; 540 case Bdiff: dval1 -= dval2; break;
496 case Bmult: dval1 *= dval2; break; 541 case Bmult: dval1 *= dval2; break;
497 case Bquo: 542 case Bquo:
498 if (dval2 == 0.0) Fsignal (Qarith_error, Qnil); 543 if (dval2 == 0.0)
544 signal_error_2 (Qarith_error, "division by zero", obj1, obj2);
499 dval1 /= dval2; 545 dval1 /= dval2;
500 break; 546 break;
501 case Bmax: if (dval1 < dval2) dval1 = dval2; break; 547 case Bmax: if (dval1 < dval2) dval1 = dval2; break;
502 case Bmin: if (dval1 > dval2) dval1 = dval2; break; 548 case Bmin: if (dval1 > dval2) dval1 = dval2; break;
503 } 549 }
538 { 584 {
539 case Bplus: ival1 += ival2; break; 585 case Bplus: ival1 += ival2; break;
540 case Bdiff: ival1 -= ival2; break; 586 case Bdiff: ival1 -= ival2; break;
541 case Bmult: ival1 *= ival2; break; 587 case Bmult: ival1 *= ival2; break;
542 case Bquo: 588 case Bquo:
543 if (ival2 == 0) Fsignal (Qarith_error, Qnil); 589 if (ival2 == 0)
590 signal_error_2 (Qarith_error, "division by zero", obj1, obj2);
544 ival1 /= ival2; 591 ival1 /= ival2;
545 break; 592 break;
546 case Bmax: if (ival1 < ival2) ival1 = ival2; break; 593 case Bmax: if (ival1 < ival2) ival1 = ival2; break;
547 case Bmin: if (ival1 > ival2) ival1 = ival2; break; 594 case Bmin: if (ival1 > ival2) ival1 = ival2; break;
548 } 595 }
556 { 603 {
557 case Bplus: dval1 += dval2; break; 604 case Bplus: dval1 += dval2; break;
558 case Bdiff: dval1 -= dval2; break; 605 case Bdiff: dval1 -= dval2; break;
559 case Bmult: dval1 *= dval2; break; 606 case Bmult: dval1 *= dval2; break;
560 case Bquo: 607 case Bquo:
561 if (dval2 == 0) Fsignal (Qarith_error, Qnil); 608 if (dval2 == 0)
609 signal_error_2 (Qarith_error, "division by zero", obj1, obj2);
562 dval1 /= dval2; 610 dval1 /= dval2;
563 break; 611 break;
564 case Bmax: if (dval1 < dval2) dval1 = dval2; break; 612 case Bmax: if (dval1 < dval2) dval1 = dval2; break;
565 case Bmin: if (dval1 > dval2) dval1 = dval2; break; 613 case Bmin: if (dval1 > dval2) dval1 = dval2; break;
566 } 614 }
612 #define JUMPR_NEXT ((void) (program_ptr += 1)) 660 #define JUMPR_NEXT ((void) (program_ptr += 1))
613 661
614 /* Push x onto the execution stack. */ 662 /* Push x onto the execution stack. */
615 #define PUSH(x) (*++stack_ptr = (x)) 663 #define PUSH(x) (*++stack_ptr = (x))
616 664
617 /* Pop a value off the execution stack. */ 665 /* Pop a value, which may be multiple, off the execution stack. */
618 #define POP (*stack_ptr--) 666 #define POP_WITH_MULTIPLE_VALUES (*stack_ptr--)
667
668 /* Pop a value off the execution stack, treating multiple values as single. */
669 #define POP (IGNORE_MULTIPLE_VALUES (POP_WITH_MULTIPLE_VALUES))
670
671 #define DISCARD_PRESERVING_MULTIPLE_VALUES(n) (stack_ptr -= (n))
619 672
620 /* Discard n values from the execution stack. */ 673 /* Discard n values from the execution stack. */
621 #define DISCARD(n) (stack_ptr -= (n)) 674 #define DISCARD(n) do { \
675 if (1 != multiple_value_current_limit) \
676 { \
677 int i, en = n; \
678 for (i = 0; i < en; i++) \
679 { \
680 *stack_ptr = ignore_multiple_values (*stack_ptr); \
681 stack_ptr--; \
682 } \
683 } \
684 else \
685 { \
686 stack_ptr -= (n); \
687 } \
688 } while (0)
689
690 /* Get the value, which may be multiple, at the top of the execution stack;
691 and leave it there. */
692 #define TOP_WITH_MULTIPLE_VALUES (*stack_ptr)
693
694 #define TOP_ADDRESS (stack_ptr)
622 695
623 /* Get the value which is at the top of the execution stack, 696 /* Get the value which is at the top of the execution stack,
624 but don't pop it. */ 697 but don't pop it. */
625 #define TOP (*stack_ptr) 698 #define TOP (IGNORE_MULTIPLE_VALUES (TOP_WITH_MULTIPLE_VALUES))
699
700 #define TOP_LVALUE (*stack_ptr)
701
702
626 703
627 /* See comment before the big switch in execute_optimized_program(). */ 704 /* See comment before the big switch in execute_optimized_program(). */
628 #define GCPRO_STACK (gcpro1.nvars = stack_ptr - stack_beg) 705 #define GCPRO_STACK (gcpro1.nvars = stack_ptr - stack_beg)
629 706
630 /* The actual interpreter for byte code. 707 /* The actual interpreter for byte code.
818 Lisp_Object val = Fget (TOP, Qbyte_code_meter, Qnil); 895 Lisp_Object val = Fget (TOP, Qbyte_code_meter, Qnil);
819 if (INTP (val)) 896 if (INTP (val))
820 Fput (TOP, Qbyte_code_meter, make_int (XINT (val) + 1)); 897 Fput (TOP, Qbyte_code_meter, make_int (XINT (val) + 1));
821 } 898 }
822 #endif 899 #endif
823 TOP = Ffuncall (n + 1, &TOP); 900 TOP_LVALUE = TOP; /* Ignore multiple values. */
901 TOP_LVALUE = Ffuncall (n + 1, TOP_ADDRESS);
824 break; 902 break;
825 903
826 case Bunbind: 904 case Bunbind:
827 case Bunbind+1: 905 case Bunbind+1:
828 case Bunbind+2: 906 case Bunbind+2:
854 else 932 else
855 JUMP_NEXT; 933 JUMP_NEXT;
856 break; 934 break;
857 935
858 case Bgotoifnilelsepop: 936 case Bgotoifnilelsepop:
859 if (NILP (TOP)) 937 /* Discard any multiple value: */
938 if (NILP (TOP_LVALUE = TOP))
860 JUMP; 939 JUMP;
861 else 940 else
862 { 941 {
863 DISCARD (1); 942 DISCARD (1);
864 JUMP_NEXT; 943 JUMP_NEXT;
865 } 944 }
866 break; 945 break;
867 946
868 case Bgotoifnonnilelsepop: 947 case Bgotoifnonnilelsepop:
869 if (!NILP (TOP)) 948 /* Discard any multiple value: */
949 if (!NILP (TOP_LVALUE = TOP))
870 JUMP; 950 JUMP;
871 else 951 else
872 { 952 {
873 DISCARD (1); 953 DISCARD (1);
874 JUMP_NEXT; 954 JUMP_NEXT;
893 else 973 else
894 JUMPR_NEXT; 974 JUMPR_NEXT;
895 break; 975 break;
896 976
897 case BRgotoifnilelsepop: 977 case BRgotoifnilelsepop:
898 if (NILP (TOP)) 978 if (NILP (TOP_LVALUE = TOP))
899 JUMPR; 979 JUMPR;
900 else 980 else
901 { 981 {
902 DISCARD (1); 982 DISCARD (1);
903 JUMPR_NEXT; 983 JUMPR_NEXT;
904 } 984 }
905 break; 985 break;
906 986
907 case BRgotoifnonnilelsepop: 987 case BRgotoifnonnilelsepop:
908 if (!NILP (TOP)) 988 if (!NILP (TOP_LVALUE = TOP))
909 JUMPR; 989 JUMPR;
910 else 990 else
911 { 991 {
912 DISCARD (1); 992 DISCARD (1);
913 JUMPR_NEXT; 993 JUMPR_NEXT;
919 #ifdef ERROR_CHECK_BYTE_CODE 999 #ifdef ERROR_CHECK_BYTE_CODE
920 /* Binds and unbinds are supposed to be compiled balanced. */ 1000 /* Binds and unbinds are supposed to be compiled balanced. */
921 if (specpdl_depth() != speccount) 1001 if (specpdl_depth() != speccount)
922 invalid_byte_code ("unbalanced specbinding stack", Qunbound); 1002 invalid_byte_code ("unbalanced specbinding stack", Qunbound);
923 #endif 1003 #endif
924 return TOP; 1004 return TOP_WITH_MULTIPLE_VALUES;
925 1005
926 case Bdiscard: 1006 case Bdiscard:
927 DISCARD (1); 1007 DISCARD (1);
928 break; 1008 break;
929 1009
930 case Bdup: 1010 case Bdup:
931 { 1011 {
932 Lisp_Object arg = TOP; 1012 Lisp_Object arg = TOP_WITH_MULTIPLE_VALUES;
933 PUSH (arg); 1013 PUSH (arg);
934 break; 1014 break;
935 } 1015 }
936 1016
937 case Bconstant2: 1017 case Bconstant2:
938 PUSH (constants_data[READ_UINT_2]); 1018 PUSH (constants_data[READ_UINT_2]);
939 break; 1019 break;
940 1020
941 case Bcar: 1021 case Bcar:
942 /* Fcar can GC via wrong_type_argument. */ 1022 {
943 /* GCPRO_STACK; */ 1023 /* Fcar can GC via wrong_type_argument. */
944 TOP = CONSP (TOP) ? XCAR (TOP) : Fcar (TOP); 1024 /* GCPRO_STACK; */
945 break; 1025 Lisp_Object arg = TOP;
1026 TOP_LVALUE = CONSP (arg) ? XCAR (arg) : Fcar (arg);
1027 break;
1028 }
946 1029
947 case Bcdr: 1030 case Bcdr:
948 /* Fcdr can GC via wrong_type_argument. */ 1031 {
949 /* GCPRO_STACK; */ 1032 /* Fcdr can GC via wrong_type_argument. */
950 TOP = CONSP (TOP) ? XCDR (TOP) : Fcdr (TOP); 1033 /* GCPRO_STACK; */
951 break; 1034 Lisp_Object arg = TOP;
952 1035 TOP_LVALUE = CONSP (arg) ? XCDR (arg) : Fcdr (arg);
1036 break;
1037 }
953 1038
954 case Bunbind_all: 1039 case Bunbind_all:
955 /* To unbind back to the beginning of this frame. Not used yet, 1040 /* To unbind back to the beginning of this frame. Not used yet,
956 but will be needed for tail-recursion elimination. */ 1041 but will be needed for tail-recursion elimination. */
957 unbind_to (speccount); 1042 unbind_to (speccount);
960 case Bnth: 1045 case Bnth:
961 { 1046 {
962 Lisp_Object arg = POP; 1047 Lisp_Object arg = POP;
963 /* Fcar and Fnthcdr can GC via wrong_type_argument. */ 1048 /* Fcar and Fnthcdr can GC via wrong_type_argument. */
964 /* GCPRO_STACK; */ 1049 /* GCPRO_STACK; */
965 TOP = Fcar (Fnthcdr (TOP, arg)); 1050 TOP_LVALUE = Fcar (Fnthcdr (TOP, arg));
966 break; 1051 break;
967 } 1052 }
968 1053
969 case Bsymbolp: 1054 case Bsymbolp:
970 TOP = SYMBOLP (TOP) ? Qt : Qnil; 1055 TOP_LVALUE = SYMBOLP (TOP) ? Qt : Qnil;
971 break; 1056 break;
972 1057
973 case Bconsp: 1058 case Bconsp:
974 TOP = CONSP (TOP) ? Qt : Qnil; 1059 TOP_LVALUE = CONSP (TOP) ? Qt : Qnil;
975 break; 1060 break;
976 1061
977 case Bstringp: 1062 case Bstringp:
978 TOP = STRINGP (TOP) ? Qt : Qnil; 1063 TOP_LVALUE = STRINGP (TOP) ? Qt : Qnil;
979 break; 1064 break;
980 1065
981 case Blistp: 1066 case Blistp:
982 TOP = LISTP (TOP) ? Qt : Qnil; 1067 TOP_LVALUE = LISTP (TOP) ? Qt : Qnil;
983 break; 1068 break;
984 1069
985 case Bnumberp: 1070 case Bnumberp:
986 #ifdef WITH_NUMBER_TYPES 1071 #ifdef WITH_NUMBER_TYPES
987 TOP = NUMBERP (TOP) ? Qt : Qnil; 1072 TOP_LVALUE = NUMBERP (TOP) ? Qt : Qnil;
988 #else 1073 #else
989 TOP = INT_OR_FLOATP (TOP) ? Qt : Qnil; 1074 TOP_LVALUE = INT_OR_FLOATP (TOP) ? Qt : Qnil;
990 #endif 1075 #endif
991 break; 1076 break;
992 1077
993 case Bintegerp: 1078 case Bintegerp:
994 #ifdef HAVE_BIGNUM 1079 #ifdef HAVE_BIGNUM
995 TOP = INTEGERP (TOP) ? Qt : Qnil; 1080 TOP_LVALUE = INTEGERP (TOP) ? Qt : Qnil;
996 #else 1081 #else
997 TOP = INTP (TOP) ? Qt : Qnil; 1082 TOP_LVALUE = INTP (TOP) ? Qt : Qnil;
998 #endif 1083 #endif
999 break; 1084 break;
1000 1085
1001 case Beq: 1086 case Beq:
1002 { 1087 {
1003 Lisp_Object arg = POP; 1088 Lisp_Object arg = POP;
1004 TOP = EQ_WITH_EBOLA_NOTICE (TOP, arg) ? Qt : Qnil; 1089 TOP_LVALUE = EQ_WITH_EBOLA_NOTICE (TOP, arg) ? Qt : Qnil;
1005 break; 1090 break;
1006 } 1091 }
1007 1092
1008 case Bnot: 1093 case Bnot:
1009 TOP = NILP (TOP) ? Qt : Qnil; 1094 TOP_LVALUE = NILP (TOP) ? Qt : Qnil;
1010 break; 1095 break;
1011 1096
1012 case Bcons: 1097 case Bcons:
1013 { 1098 {
1014 Lisp_Object arg = POP; 1099 Lisp_Object arg = POP;
1015 TOP = Fcons (TOP, arg); 1100 TOP_LVALUE = Fcons (TOP, arg);
1016 break; 1101 break;
1017 } 1102 }
1018 1103
1019 case Blist1: 1104 case Blist1:
1020 TOP = Fcons (TOP, Qnil); 1105 TOP_LVALUE = Fcons (TOP, Qnil);
1021 break; 1106 break;
1022 1107
1023 1108
1024 case BlistN: 1109 case BlistN:
1025 n = READ_UINT_1; 1110 n = READ_UINT_1;
1038 if (--n) 1123 if (--n)
1039 { 1124 {
1040 DISCARD (1); 1125 DISCARD (1);
1041 goto list_loop; 1126 goto list_loop;
1042 } 1127 }
1043 TOP = list; 1128 TOP_LVALUE = list;
1044 break; 1129 break;
1045 } 1130 }
1046 1131
1047 1132
1048 case Bconcat2: 1133 case Bconcat2:
1056 n = READ_UINT_1; 1141 n = READ_UINT_1;
1057 do_concat: 1142 do_concat:
1058 DISCARD (n - 1); 1143 DISCARD (n - 1);
1059 /* Apparently `concat' can GC; Fconcat GCPROs its arguments. */ 1144 /* Apparently `concat' can GC; Fconcat GCPROs its arguments. */
1060 /* GCPRO_STACK; */ 1145 /* GCPRO_STACK; */
1061 TOP = Fconcat (n, &TOP); 1146 TOP_LVALUE = TOP; /* Ignore multiple values. */
1147 TOP_LVALUE = Fconcat (n, TOP_ADDRESS);
1062 break; 1148 break;
1063 1149
1064 1150
1065 case Blength: 1151 case Blength:
1066 TOP = Flength (TOP); 1152 TOP_LVALUE = Flength (TOP);
1067 break; 1153 break;
1068 1154
1069 case Baset: 1155 case Baset:
1070 { 1156 {
1071 Lisp_Object arg2 = POP; 1157 Lisp_Object arg2 = POP;
1072 Lisp_Object arg1 = POP; 1158 Lisp_Object arg1 = POP;
1073 TOP = Faset (TOP, arg1, arg2); 1159 TOP_LVALUE = Faset (TOP, arg1, arg2);
1074 break; 1160 break;
1075 } 1161 }
1076 1162
1077 case Bsymbol_value: 1163 case Bsymbol_value:
1078 /* Why does this need GCPRO_STACK? If not, remove others, too. */ 1164 /* Why does this need GCPRO_STACK? If not, remove others, too. */
1079 /* GCPRO_STACK; */ 1165 /* GCPRO_STACK; */
1080 TOP = Fsymbol_value (TOP); 1166 TOP_LVALUE = Fsymbol_value (TOP);
1081 break; 1167 break;
1082 1168
1083 case Bsymbol_function: 1169 case Bsymbol_function:
1084 TOP = Fsymbol_function (TOP); 1170 TOP_LVALUE = Fsymbol_function (TOP);
1085 break; 1171 break;
1086 1172
1087 case Bget: 1173 case Bget:
1088 { 1174 {
1089 Lisp_Object arg = POP; 1175 Lisp_Object arg = POP;
1090 TOP = Fget (TOP, arg, Qnil); 1176 TOP_LVALUE = Fget (TOP, arg, Qnil);
1091 break; 1177 break;
1092 } 1178 }
1093 1179
1094 case Bsub1: 1180 case Bsub1:
1181 {
1095 #ifdef HAVE_BIGNUM 1182 #ifdef HAVE_BIGNUM
1096 TOP = Fsub1 (TOP); 1183 TOP_LVALUE = Fsub1 (TOP);
1097 #else 1184 #else
1098 TOP = INTP (TOP) ? INT_MINUS1 (TOP) : Fsub1 (TOP); 1185 Lisp_Object arg = TOP;
1099 #endif 1186 TOP_LVALUE = INTP (arg) ? INT_MINUS1 (arg) : Fsub1 (arg);
1100 break; 1187 #endif
1101 1188 break;
1189 }
1102 case Badd1: 1190 case Badd1:
1191 {
1103 #ifdef HAVE_BIGNUM 1192 #ifdef HAVE_BIGNUM
1104 TOP = Fadd1 (TOP); 1193 TOP_LVALUE = Fadd1 (TOP);
1105 #else 1194 #else
1106 TOP = INTP (TOP) ? INT_PLUS1 (TOP) : Fadd1 (TOP); 1195 Lisp_Object arg = TOP;
1107 #endif 1196 TOP_LVALUE = INTP (arg) ? INT_PLUS1 (arg) : Fadd1 (arg);
1108 break; 1197 #endif
1109 1198 break;
1199 }
1110 1200
1111 case Beqlsign: 1201 case Beqlsign:
1112 { 1202 {
1113 Lisp_Object arg = POP; 1203 Lisp_Object arg = POP;
1114 TOP = bytecode_arithcompare (TOP, arg) == 0 ? Qt : Qnil; 1204 TOP_LVALUE = bytecode_arithcompare (TOP, arg) == 0 ? Qt : Qnil;
1115 break; 1205 break;
1116 } 1206 }
1117 1207
1118 case Bgtr: 1208 case Bgtr:
1119 { 1209 {
1120 Lisp_Object arg = POP; 1210 Lisp_Object arg = POP;
1121 TOP = bytecode_arithcompare (TOP, arg) > 0 ? Qt : Qnil; 1211 TOP_LVALUE = bytecode_arithcompare (TOP, arg) > 0 ? Qt : Qnil;
1122 break; 1212 break;
1123 } 1213 }
1124 1214
1125 case Blss: 1215 case Blss:
1126 { 1216 {
1127 Lisp_Object arg = POP; 1217 Lisp_Object arg = POP;
1128 TOP = bytecode_arithcompare (TOP, arg) < 0 ? Qt : Qnil; 1218 TOP_LVALUE = bytecode_arithcompare (TOP, arg) < 0 ? Qt : Qnil;
1129 break; 1219 break;
1130 } 1220 }
1131 1221
1132 case Bleq: 1222 case Bleq:
1133 { 1223 {
1134 Lisp_Object arg = POP; 1224 Lisp_Object arg = POP;
1135 TOP = bytecode_arithcompare (TOP, arg) <= 0 ? Qt : Qnil; 1225 TOP_LVALUE = bytecode_arithcompare (TOP, arg) <= 0 ? Qt : Qnil;
1136 break; 1226 break;
1137 } 1227 }
1138 1228
1139 case Bgeq: 1229 case Bgeq:
1140 { 1230 {
1141 Lisp_Object arg = POP; 1231 Lisp_Object arg = POP;
1142 TOP = bytecode_arithcompare (TOP, arg) >= 0 ? Qt : Qnil; 1232 TOP_LVALUE = bytecode_arithcompare (TOP, arg) >= 0 ? Qt : Qnil;
1143 break; 1233 break;
1144 } 1234 }
1145 1235
1146 1236
1147 case Bnegate: 1237 case Bnegate:
1148 TOP = bytecode_negate (TOP); 1238 TOP_LVALUE = bytecode_negate (TOP);
1149 break; 1239 break;
1150 1240
1151 case Bnconc: 1241 case Bnconc:
1152 DISCARD (1); 1242 DISCARD (1);
1153 /* nconc2 GCPROs before calling this. */ 1243 /* nconc2 GCPROs before calling this. */
1154 /* GCPRO_STACK; */ 1244 /* GCPRO_STACK; */
1155 TOP = bytecode_nconc2 (&TOP); 1245 TOP_LVALUE = TOP; /* Ignore multiple values. */
1246 TOP_LVALUE = bytecode_nconc2 (TOP_ADDRESS);
1156 break; 1247 break;
1157 1248
1158 case Bplus: 1249 case Bplus:
1159 { 1250 {
1160 Lisp_Object arg2 = POP; 1251 Lisp_Object arg2 = POP;
1161 Lisp_Object arg1 = TOP; 1252 Lisp_Object arg1 = TOP;
1162 #ifdef HAVE_BIGNUM 1253 #ifdef HAVE_BIGNUM
1163 TOP = bytecode_arithop (arg1, arg2, opcode); 1254 TOP_LVALUE = bytecode_arithop (arg1, arg2, opcode);
1164 #else 1255 #else
1165 TOP = INTP (arg1) && INTP (arg2) ? 1256 TOP_LVALUE = INTP (arg1) && INTP (arg2) ?
1166 INT_PLUS (arg1, arg2) : 1257 INT_PLUS (arg1, arg2) :
1167 bytecode_arithop (arg1, arg2, opcode); 1258 bytecode_arithop (arg1, arg2, opcode);
1168 #endif 1259 #endif
1169 break; 1260 break;
1170 } 1261 }
1172 case Bdiff: 1263 case Bdiff:
1173 { 1264 {
1174 Lisp_Object arg2 = POP; 1265 Lisp_Object arg2 = POP;
1175 Lisp_Object arg1 = TOP; 1266 Lisp_Object arg1 = TOP;
1176 #ifdef HAVE_BIGNUM 1267 #ifdef HAVE_BIGNUM
1177 TOP = bytecode_arithop (arg1, arg2, opcode); 1268 TOP_LVALUE = bytecode_arithop (arg1, arg2, opcode);
1178 #else 1269 #else
1179 TOP = INTP (arg1) && INTP (arg2) ? 1270 TOP_LVALUE = INTP (arg1) && INTP (arg2) ?
1180 INT_MINUS (arg1, arg2) : 1271 INT_MINUS (arg1, arg2) :
1181 bytecode_arithop (arg1, arg2, opcode); 1272 bytecode_arithop (arg1, arg2, opcode);
1182 #endif 1273 #endif
1183 break; 1274 break;
1184 } 1275 }
1187 case Bquo: 1278 case Bquo:
1188 case Bmax: 1279 case Bmax:
1189 case Bmin: 1280 case Bmin:
1190 { 1281 {
1191 Lisp_Object arg = POP; 1282 Lisp_Object arg = POP;
1192 TOP = bytecode_arithop (TOP, arg, opcode); 1283 TOP_LVALUE = bytecode_arithop (TOP, arg, opcode);
1193 break; 1284 break;
1194 } 1285 }
1195 1286
1196 case Bpoint: 1287 case Bpoint:
1197 PUSH (make_int (BUF_PT (current_buffer))); 1288 PUSH (make_int (BUF_PT (current_buffer)));
1198 break; 1289 break;
1199 1290
1200 case Binsert: 1291 case Binsert:
1201 /* Says it can GC. */ 1292 /* Says it can GC. */
1202 /* GCPRO_STACK; */ 1293 /* GCPRO_STACK; */
1203 TOP = Finsert (1, &TOP); 1294 TOP_LVALUE = TOP; /* Ignore multiple values. */
1295 TOP_LVALUE = Finsert (1, TOP_ADDRESS);
1204 break; 1296 break;
1205 1297
1206 case BinsertN: 1298 case BinsertN:
1207 n = READ_UINT_1; 1299 n = READ_UINT_1;
1208 DISCARD (n - 1); 1300 DISCARD (n - 1);
1209 /* See Binsert. */ 1301 /* See Binsert. */
1210 /* GCPRO_STACK; */ 1302 /* GCPRO_STACK; */
1211 TOP = Finsert (n, &TOP); 1303 TOP_LVALUE = TOP; /* Ignore multiple values. */
1304 TOP_LVALUE = Finsert (n, TOP_ADDRESS);
1212 break; 1305 break;
1213 1306
1214 case Baref: 1307 case Baref:
1215 { 1308 {
1216 Lisp_Object arg = POP; 1309 Lisp_Object arg = POP;
1217 TOP = Faref (TOP, arg); 1310 TOP_LVALUE = Faref (TOP, arg);
1218 break; 1311 break;
1219 } 1312 }
1220 1313
1221 case Bmemq: 1314 case Bmemq:
1222 { 1315 {
1223 Lisp_Object arg = POP; 1316 Lisp_Object arg = POP;
1224 TOP = Fmemq (TOP, arg); 1317 TOP_LVALUE = Fmemq (TOP, arg);
1225 break; 1318 break;
1226 } 1319 }
1227 1320
1228 case Bset: 1321 case Bset:
1229 { 1322 {
1230 Lisp_Object arg = POP; 1323 Lisp_Object arg = POP;
1231 /* Fset may call magic handlers */ 1324 /* Fset may call magic handlers */
1232 /* GCPRO_STACK; */ 1325 /* GCPRO_STACK; */
1233 TOP = Fset (TOP, arg); 1326 TOP_LVALUE = Fset (TOP, arg);
1234 break; 1327 break;
1235 } 1328 }
1236 1329
1237 case Bequal: 1330 case Bequal:
1238 { 1331 {
1239 Lisp_Object arg = POP; 1332 Lisp_Object arg = POP;
1240 /* Can QUIT, so can GC, right? */ 1333 /* Can QUIT, so can GC, right? */
1241 /* GCPRO_STACK; */ 1334 /* GCPRO_STACK; */
1242 TOP = Fequal (TOP, arg); 1335 TOP_LVALUE = Fequal (TOP, arg);
1243 break; 1336 break;
1244 } 1337 }
1245 1338
1246 case Bnthcdr: 1339 case Bnthcdr:
1247 { 1340 {
1248 Lisp_Object arg = POP; 1341 Lisp_Object arg = POP;
1249 TOP = Fnthcdr (TOP, arg); 1342 TOP_LVALUE = Fnthcdr (TOP, arg);
1250 break; 1343 break;
1251 } 1344 }
1252 1345
1253 case Belt: 1346 case Belt:
1254 { 1347 {
1255 Lisp_Object arg = POP; 1348 Lisp_Object arg = POP;
1256 TOP = Felt (TOP, arg); 1349 TOP_LVALUE = Felt (TOP, arg);
1257 break; 1350 break;
1258 } 1351 }
1259 1352
1260 case Bmember: 1353 case Bmember:
1261 { 1354 {
1262 Lisp_Object arg = POP; 1355 Lisp_Object arg = POP;
1263 /* Can QUIT, so can GC, right? */ 1356 /* Can QUIT, so can GC, right? */
1264 /* GCPRO_STACK; */ 1357 /* GCPRO_STACK; */
1265 TOP = Fmember (TOP, arg); 1358 TOP_LVALUE = Fmember (TOP, arg);
1266 break; 1359 break;
1267 } 1360 }
1268 1361
1269 case Bgoto_char: 1362 case Bgoto_char:
1270 TOP = Fgoto_char (TOP, Qnil); 1363 TOP_LVALUE = Fgoto_char (TOP, Qnil);
1271 break; 1364 break;
1272 1365
1273 case Bcurrent_buffer: 1366 case Bcurrent_buffer:
1274 { 1367 {
1275 Lisp_Object buffer = wrap_buffer (current_buffer); 1368 Lisp_Object buffer = wrap_buffer (current_buffer);
1280 1373
1281 case Bset_buffer: 1374 case Bset_buffer:
1282 /* #### WAG: set-buffer may cause Fset's of buffer locals 1375 /* #### WAG: set-buffer may cause Fset's of buffer locals
1283 Didn't prevent crash. :-( */ 1376 Didn't prevent crash. :-( */
1284 /* GCPRO_STACK; */ 1377 /* GCPRO_STACK; */
1285 TOP = Fset_buffer (TOP); 1378 TOP_LVALUE = Fset_buffer (TOP);
1286 break; 1379 break;
1287 1380
1288 case Bpoint_max: 1381 case Bpoint_max:
1289 PUSH (make_int (BUF_ZV (current_buffer))); 1382 PUSH (make_int (BUF_ZV (current_buffer)));
1290 break; 1383 break;
1296 case Bskip_chars_forward: 1389 case Bskip_chars_forward:
1297 { 1390 {
1298 Lisp_Object arg = POP; 1391 Lisp_Object arg = POP;
1299 /* Can QUIT, so can GC, right? */ 1392 /* Can QUIT, so can GC, right? */
1300 /* GCPRO_STACK; */ 1393 /* GCPRO_STACK; */
1301 TOP = Fskip_chars_forward (TOP, arg, Qnil); 1394 TOP_LVALUE = Fskip_chars_forward (TOP, arg, Qnil);
1302 break; 1395 break;
1303 } 1396 }
1304 1397
1305 case Bassq: 1398 case Bassq:
1306 { 1399 {
1307 Lisp_Object arg = POP; 1400 Lisp_Object arg = POP;
1308 TOP = Fassq (TOP, arg); 1401 TOP_LVALUE = Fassq (TOP, arg);
1309 break; 1402 break;
1310 } 1403 }
1311 1404
1312 case Bsetcar: 1405 case Bsetcar:
1313 { 1406 {
1314 Lisp_Object arg = POP; 1407 Lisp_Object arg = POP;
1315 TOP = Fsetcar (TOP, arg); 1408 TOP_LVALUE = Fsetcar (TOP, arg);
1316 break; 1409 break;
1317 } 1410 }
1318 1411
1319 case Bsetcdr: 1412 case Bsetcdr:
1320 { 1413 {
1321 Lisp_Object arg = POP; 1414 Lisp_Object arg = POP;
1322 TOP = Fsetcdr (TOP, arg); 1415 TOP_LVALUE = Fsetcdr (TOP, arg);
1323 break; 1416 break;
1324 } 1417 }
1325 1418
1326 case Bnreverse: 1419 case Bnreverse:
1327 TOP = bytecode_nreverse (TOP); 1420 TOP_LVALUE = bytecode_nreverse (TOP);
1328 break; 1421 break;
1329 1422
1330 case Bcar_safe: 1423 case Bcar_safe:
1331 TOP = CONSP (TOP) ? XCAR (TOP) : Qnil; 1424 TOP_LVALUE = CONSP (TOP) ? XCAR (TOP) : Qnil;
1332 break; 1425 break;
1333 1426
1334 case Bcdr_safe: 1427 case Bcdr_safe:
1335 TOP = CONSP (TOP) ? XCDR (TOP) : Qnil; 1428 TOP_LVALUE = CONSP (TOP) ? XCDR (TOP) : Qnil;
1336 break; 1429 break;
1337 1430
1338 } 1431 }
1339 } 1432 }
1340 } 1433 }
1349 Lisp_Object * 1442 Lisp_Object *
1350 execute_rare_opcode (Lisp_Object *stack_ptr, 1443 execute_rare_opcode (Lisp_Object *stack_ptr,
1351 const Opbyte *UNUSED (program_ptr), 1444 const Opbyte *UNUSED (program_ptr),
1352 Opcode opcode) 1445 Opcode opcode)
1353 { 1446 {
1447 REGISTER int n;
1448
1354 switch (opcode) 1449 switch (opcode)
1355 { 1450 {
1356 1451
1357 case Bsave_excursion: 1452 case Bsave_excursion:
1358 record_unwind_protect (save_excursion_restore, 1453 record_unwind_protect (save_excursion_restore,
1359 save_excursion_save ()); 1454 save_excursion_save ());
1360 break; 1455 break;
1361 1456
1457 /* This bytecode will eventually go away, once we no longer encounter
1458 byte code from 21.4. In 21.5.10 and newer, save-window-excursion is
1459 a macro. */
1362 case Bsave_window_excursion: 1460 case Bsave_window_excursion:
1363 { 1461 {
1364 int count = specpdl_depth (); 1462 int count = specpdl_depth ();
1365 record_unwind_protect (save_window_excursion_unwind, 1463 record_unwind_protect (Feval,
1366 call1 (Qcurrent_window_configuration, Qnil)); 1464 list2 (Qset_window_configuration,
1367 TOP = Fprogn (TOP); 1465 call0 (Qcurrent_window_configuration)));
1466 TOP_LVALUE = Fprogn (TOP);
1368 unbind_to (count); 1467 unbind_to (count);
1369 break; 1468 break;
1370 } 1469 }
1371 1470
1372 case Bsave_restriction: 1471 case Bsave_restriction:
1375 break; 1474 break;
1376 1475
1377 case Bcatch: 1476 case Bcatch:
1378 { 1477 {
1379 Lisp_Object arg = POP; 1478 Lisp_Object arg = POP;
1380 TOP = internal_catch (TOP, Feval, arg, 0, 0, 0); 1479 TOP_LVALUE = internal_catch (TOP, Feval, arg, 0, 0, 0);
1381 break; 1480 break;
1382 } 1481 }
1383 1482
1384 case Bskip_chars_backward: 1483 case Bskip_chars_backward:
1385 { 1484 {
1386 Lisp_Object arg = POP; 1485 Lisp_Object arg = POP;
1387 TOP = Fskip_chars_backward (TOP, arg, Qnil); 1486 TOP_LVALUE = Fskip_chars_backward (TOP, arg, Qnil);
1388 break; 1487 break;
1389 } 1488 }
1390 1489
1391 case Bunwind_protect: 1490 case Bunwind_protect:
1392 record_unwind_protect (Fprogn, POP); 1491 record_unwind_protect (Fprogn, POP);
1394 1493
1395 case Bcondition_case: 1494 case Bcondition_case:
1396 { 1495 {
1397 Lisp_Object arg2 = POP; /* handlers */ 1496 Lisp_Object arg2 = POP; /* handlers */
1398 Lisp_Object arg1 = POP; /* bodyform */ 1497 Lisp_Object arg1 = POP; /* bodyform */
1399 TOP = condition_case_3 (arg1, TOP, arg2); 1498 TOP_LVALUE = condition_case_3 (arg1, TOP, arg2);
1400 break; 1499 break;
1401 } 1500 }
1402 1501
1403 case Bset_marker: 1502 case Bset_marker:
1404 { 1503 {
1405 Lisp_Object arg2 = POP; 1504 Lisp_Object arg2 = POP;
1406 Lisp_Object arg1 = POP; 1505 Lisp_Object arg1 = POP;
1407 TOP = Fset_marker (TOP, arg1, arg2); 1506 TOP_LVALUE = Fset_marker (TOP, arg1, arg2);
1408 break; 1507 break;
1409 } 1508 }
1410 1509
1411 case Brem: 1510 case Brem:
1412 { 1511 {
1413 Lisp_Object arg = POP; 1512 Lisp_Object arg = POP;
1414 TOP = Frem (TOP, arg); 1513 TOP_LVALUE = Frem (TOP, arg);
1415 break; 1514 break;
1416 } 1515 }
1417 1516
1418 case Bmatch_beginning: 1517 case Bmatch_beginning:
1419 TOP = Fmatch_beginning (TOP); 1518 TOP_LVALUE = Fmatch_beginning (TOP);
1420 break; 1519 break;
1421 1520
1422 case Bmatch_end: 1521 case Bmatch_end:
1423 TOP = Fmatch_end (TOP); 1522 TOP_LVALUE = Fmatch_end (TOP);
1424 break; 1523 break;
1425 1524
1426 case Bupcase: 1525 case Bupcase:
1427 TOP = Fupcase (TOP, Qnil); 1526 TOP_LVALUE = Fupcase (TOP, Qnil);
1428 break; 1527 break;
1429 1528
1430 case Bdowncase: 1529 case Bdowncase:
1431 TOP = Fdowncase (TOP, Qnil); 1530 TOP_LVALUE = Fdowncase (TOP, Qnil);
1432 break; 1531 break;
1433 1532
1434 case Bfset: 1533 case Bfset:
1435 { 1534 {
1436 Lisp_Object arg = POP; 1535 Lisp_Object arg = POP;
1437 TOP = Ffset (TOP, arg); 1536 TOP_LVALUE = Ffset (TOP, arg);
1438 break; 1537 break;
1439 } 1538 }
1440 1539
1441 case Bstring_equal: 1540 case Bstring_equal:
1442 { 1541 {
1443 Lisp_Object arg = POP; 1542 Lisp_Object arg = POP;
1444 TOP = Fstring_equal (TOP, arg); 1543 TOP_LVALUE = Fstring_equal (TOP, arg);
1445 break; 1544 break;
1446 } 1545 }
1447 1546
1448 case Bstring_lessp: 1547 case Bstring_lessp:
1449 { 1548 {
1450 Lisp_Object arg = POP; 1549 Lisp_Object arg = POP;
1451 TOP = Fstring_lessp (TOP, arg); 1550 TOP_LVALUE = Fstring_lessp (TOP, arg);
1452 break; 1551 break;
1453 } 1552 }
1454 1553
1455 case Bsubstring: 1554 case Bsubstring:
1456 { 1555 {
1457 Lisp_Object arg2 = POP; 1556 Lisp_Object arg2 = POP;
1458 Lisp_Object arg1 = POP; 1557 Lisp_Object arg1 = POP;
1459 TOP = Fsubstring (TOP, arg1, arg2); 1558 TOP_LVALUE = Fsubstring (TOP, arg1, arg2);
1460 break; 1559 break;
1461 } 1560 }
1462 1561
1463 case Bcurrent_column: 1562 case Bcurrent_column:
1464 PUSH (make_int (current_column (current_buffer))); 1563 PUSH (make_int (current_column (current_buffer)));
1465 break; 1564 break;
1466 1565
1467 case Bchar_after: 1566 case Bchar_after:
1468 TOP = Fchar_after (TOP, Qnil); 1567 TOP_LVALUE = Fchar_after (TOP, Qnil);
1469 break; 1568 break;
1470 1569
1471 case Bindent_to: 1570 case Bindent_to:
1472 TOP = Findent_to (TOP, Qnil, Qnil); 1571 TOP_LVALUE = Findent_to (TOP, Qnil, Qnil);
1473 break; 1572 break;
1474 1573
1475 case Bwiden: 1574 case Bwiden:
1476 PUSH (Fwiden (Qnil)); 1575 PUSH (Fwiden (Qnil));
1477 break; 1576 break;
1508 case Binteractive_p: 1607 case Binteractive_p:
1509 PUSH (Finteractive_p ()); 1608 PUSH (Finteractive_p ());
1510 break; 1609 break;
1511 1610
1512 case Bforward_char: 1611 case Bforward_char:
1513 TOP = Fforward_char (TOP, Qnil); 1612 TOP_LVALUE = Fforward_char (TOP, Qnil);
1514 break; 1613 break;
1515 1614
1516 case Bforward_word: 1615 case Bforward_word:
1517 TOP = Fforward_word (TOP, Qnil); 1616 TOP_LVALUE = Fforward_word (TOP, Qnil);
1518 break; 1617 break;
1519 1618
1520 case Bforward_line: 1619 case Bforward_line:
1521 TOP = Fforward_line (TOP, Qnil); 1620 TOP_LVALUE = Fforward_line (TOP, Qnil);
1522 break; 1621 break;
1523 1622
1524 case Bchar_syntax: 1623 case Bchar_syntax:
1525 TOP = Fchar_syntax (TOP, Qnil); 1624 TOP_LVALUE = Fchar_syntax (TOP, Qnil);
1526 break; 1625 break;
1527 1626
1528 case Bbuffer_substring: 1627 case Bbuffer_substring:
1529 { 1628 {
1530 Lisp_Object arg = POP; 1629 Lisp_Object arg = POP;
1531 TOP = Fbuffer_substring (TOP, arg, Qnil); 1630 TOP_LVALUE = Fbuffer_substring (TOP, arg, Qnil);
1532 break; 1631 break;
1533 } 1632 }
1534 1633
1535 case Bdelete_region: 1634 case Bdelete_region:
1536 { 1635 {
1537 Lisp_Object arg = POP; 1636 Lisp_Object arg = POP;
1538 TOP = Fdelete_region (TOP, arg, Qnil); 1637 TOP_LVALUE = Fdelete_region (TOP, arg, Qnil);
1539 break; 1638 break;
1540 } 1639 }
1541 1640
1542 case Bnarrow_to_region: 1641 case Bnarrow_to_region:
1543 { 1642 {
1544 Lisp_Object arg = POP; 1643 Lisp_Object arg = POP;
1545 TOP = Fnarrow_to_region (TOP, arg, Qnil); 1644 TOP_LVALUE = Fnarrow_to_region (TOP, arg, Qnil);
1546 break; 1645 break;
1547 } 1646 }
1548 1647
1549 case Bend_of_line: 1648 case Bend_of_line:
1550 TOP = Fend_of_line (TOP, Qnil); 1649 TOP_LVALUE = Fend_of_line (TOP, Qnil);
1551 break; 1650 break;
1552 1651
1553 case Btemp_output_buffer_setup: 1652 case Btemp_output_buffer_setup:
1554 temp_output_buffer_setup (TOP); 1653 temp_output_buffer_setup (TOP);
1555 TOP = Vstandard_output; 1654 TOP_LVALUE = Vstandard_output;
1556 break; 1655 break;
1557 1656
1558 case Btemp_output_buffer_show: 1657 case Btemp_output_buffer_show:
1559 { 1658 {
1560 Lisp_Object arg = POP; 1659 Lisp_Object arg = POP;
1561 temp_output_buffer_show (TOP, Qnil); 1660 temp_output_buffer_show (TOP, Qnil);
1562 TOP = arg; 1661 TOP_LVALUE = arg;
1563 /* GAG ME!! */ 1662 /* GAG ME!! */
1564 /* pop binding of standard-output */ 1663 /* pop binding of standard-output */
1565 unbind_to (specpdl_depth() - 1); 1664 unbind_to (specpdl_depth() - 1);
1566 break; 1665 break;
1567 } 1666 }
1568 1667
1569 case Bold_eq: 1668 case Bold_eq:
1570 { 1669 {
1571 Lisp_Object arg = POP; 1670 Lisp_Object arg = POP;
1572 TOP = HACKEQ_UNSAFE (TOP, arg) ? Qt : Qnil; 1671 TOP_LVALUE = HACKEQ_UNSAFE (TOP, arg) ? Qt : Qnil;
1573 break; 1672 break;
1574 } 1673 }
1575 1674
1576 case Bold_memq: 1675 case Bold_memq:
1577 { 1676 {
1578 Lisp_Object arg = POP; 1677 Lisp_Object arg = POP;
1579 TOP = Fold_memq (TOP, arg); 1678 TOP_LVALUE = Fold_memq (TOP, arg);
1580 break; 1679 break;
1581 } 1680 }
1582 1681
1583 case Bold_equal: 1682 case Bold_equal:
1584 { 1683 {
1585 Lisp_Object arg = POP; 1684 Lisp_Object arg = POP;
1586 TOP = Fold_equal (TOP, arg); 1685 TOP_LVALUE = Fold_equal (TOP, arg);
1587 break; 1686 break;
1588 } 1687 }
1589 1688
1590 case Bold_member: 1689 case Bold_member:
1591 { 1690 {
1592 Lisp_Object arg = POP; 1691 Lisp_Object arg = POP;
1593 TOP = Fold_member (TOP, arg); 1692 TOP_LVALUE = Fold_member (TOP, arg);
1594 break; 1693 break;
1595 } 1694 }
1596 1695
1597 case Bold_assq: 1696 case Bold_assq:
1598 { 1697 {
1599 Lisp_Object arg = POP; 1698 Lisp_Object arg = POP;
1600 TOP = Fold_assq (TOP, arg); 1699 TOP_LVALUE = Fold_assq (TOP, arg);
1601 break; 1700 break;
1701 }
1702
1703 case Bbind_multiple_value_limits:
1704 {
1705 Lisp_Object upper = POP, first = TOP, speccount;
1706
1707 CHECK_NATNUM (upper);
1708 CHECK_NATNUM (first);
1709
1710 speccount = make_int (bind_multiple_value_limits (XINT (first),
1711 XINT (upper)));
1712 PUSH (upper);
1713 PUSH (speccount);
1714 break;
1715 }
1716
1717 case Bmultiple_value_call:
1718 {
1719 n = XINT (POP);
1720 DISCARD_PRESERVING_MULTIPLE_VALUES (n - 1);
1721 /* Discard multiple values for the first (function) argument: */
1722 TOP_LVALUE = TOP;
1723 TOP_LVALUE = multiple_value_call (n, TOP_ADDRESS);
1724 break;
1725 }
1726
1727 case Bmultiple_value_list_internal:
1728 {
1729 DISCARD_PRESERVING_MULTIPLE_VALUES (3);
1730 TOP_LVALUE = multiple_value_list_internal (4, TOP_ADDRESS);
1731 break;
1732 }
1733
1734 case Bthrow:
1735 {
1736 Lisp_Object arg = POP_WITH_MULTIPLE_VALUES;
1737
1738 /* We never throw to a catch tag that is a multiple value: */
1739 throw_or_bomb_out (TOP, arg, 0, Qnil, Qnil);
1740 break;
1602 } 1741 }
1603 1742
1604 default: 1743 default:
1605 ABORT(); 1744 ABORT();
1606 break; 1745 break;
2020 } 2159 }
2021 } 2160 }
2022 } 2161 }
2023 2162
2024 if (totalargs) 2163 if (totalargs)
2164 #ifdef NEW_GC
2165 f->arguments = make_compiled_function_args (totalargs);
2166 #else /* not NEW_GC */
2025 f->args = xnew_array (Lisp_Object, totalargs); 2167 f->args = xnew_array (Lisp_Object, totalargs);
2168 #endif /* not NEW_GC */
2026 2169
2027 { 2170 {
2028 LIST_LOOP_2 (arg, f->arglist) 2171 LIST_LOOP_2 (arg, f->arglist)
2029 { 2172 {
2030 if (!EQ (arg, Qand_optional) && !EQ (arg, Qand_rest)) 2173 if (!EQ (arg, Qand_optional) && !EQ (arg, Qand_rest))
2174 #ifdef NEW_GC
2175 XCOMPILED_FUNCTION_ARGS_DATA (f->arguments)[i++] = arg;
2176 #else /* not NEW_GC */
2031 f->args[i++] = arg; 2177 f->args[i++] = arg;
2178 #endif /* not NEW_GC */
2032 } 2179 }
2033 } 2180 }
2034 2181
2035 f->max_args = maxargs; 2182 f->max_args = maxargs;
2036 f->min_args = minargs; 2183 f->min_args = minargs;
2059 } 2206 }
2060 2207
2061 /************************************************************************/ 2208 /************************************************************************/
2062 /* The compiled-function object type */ 2209 /* The compiled-function object type */
2063 /************************************************************************/ 2210 /************************************************************************/
2211
2064 static void 2212 static void
2065 print_compiled_function (Lisp_Object obj, Lisp_Object printcharfun, 2213 print_compiled_function (Lisp_Object obj, Lisp_Object printcharfun,
2066 int escapeflag) 2214 int escapeflag)
2067 { 2215 {
2068 /* This function can GC */ 2216 /* This function can GC */
2141 mark_object (f->doc_and_interactive); 2289 mark_object (f->doc_and_interactive);
2142 #ifdef COMPILED_FUNCTION_ANNOTATION_HACK 2290 #ifdef COMPILED_FUNCTION_ANNOTATION_HACK
2143 mark_object (f->annotated); 2291 mark_object (f->annotated);
2144 #endif 2292 #endif
2145 for (i = 0; i < f->args_in_array; i++) 2293 for (i = 0; i < f->args_in_array; i++)
2294 #ifdef NEW_GC
2295 mark_object (XCOMPILED_FUNCTION_ARGS_DATA (f->arguments)[i]);
2296 #else /* not NEW_GC */
2146 mark_object (f->args[i]); 2297 mark_object (f->args[i]);
2298 #endif /* not NEW_GC */
2147 2299
2148 /* tail-recurse on constants */ 2300 /* tail-recurse on constants */
2149 return f->constants; 2301 return f->constants;
2150 } 2302 }
2151 2303
2177 internal_hash (f->constants, depth + 1)); 2329 internal_hash (f->constants, depth + 1));
2178 } 2330 }
2179 2331
2180 static const struct memory_description compiled_function_description[] = { 2332 static const struct memory_description compiled_function_description[] = {
2181 { XD_INT, offsetof (Lisp_Compiled_Function, args_in_array) }, 2333 { XD_INT, offsetof (Lisp_Compiled_Function, args_in_array) },
2182 { XD_BLOCK_PTR, offsetof (Lisp_Compiled_Function, args), 2334 #ifdef NEW_GC
2335 { XD_LISP_OBJECT, offsetof (Lisp_Compiled_Function, arguments) },
2336 #else /* not NEW_GC */
2337 { XD_BLOCK_PTR, offsetof (Lisp_Compiled_Function, args),
2183 XD_INDIRECT (0, 0), { &lisp_object_description } }, 2338 XD_INDIRECT (0, 0), { &lisp_object_description } },
2339 #endif /* not NEW_GC */
2184 { XD_LISP_OBJECT, offsetof (Lisp_Compiled_Function, instructions) }, 2340 { XD_LISP_OBJECT, offsetof (Lisp_Compiled_Function, instructions) },
2185 { XD_LISP_OBJECT, offsetof (Lisp_Compiled_Function, constants) }, 2341 { XD_LISP_OBJECT, offsetof (Lisp_Compiled_Function, constants) },
2186 { XD_LISP_OBJECT, offsetof (Lisp_Compiled_Function, arglist) }, 2342 { XD_LISP_OBJECT, offsetof (Lisp_Compiled_Function, arglist) },
2187 { XD_LISP_OBJECT, offsetof (Lisp_Compiled_Function, doc_and_interactive) }, 2343 { XD_LISP_OBJECT, offsetof (Lisp_Compiled_Function, doc_and_interactive) },
2188 #ifdef COMPILED_FUNCTION_ANNOTATION_HACK 2344 #ifdef COMPILED_FUNCTION_ANNOTATION_HACK
2189 { XD_LISP_OBJECT, offsetof (Lisp_Compiled_Function, annotated) }, 2345 { XD_LISP_OBJECT, offsetof (Lisp_Compiled_Function, annotated) },
2190 #endif 2346 #endif
2191 { XD_END } 2347 { XD_END }
2192 }; 2348 };
2193 2349
2194 #ifdef MC_ALLOC 2350 DEFINE_DUMPABLE_FROB_BLOCK_LISP_OBJECT ("compiled-function", compiled_function,
2195 static void
2196 finalize_compiled_function (void *header, int for_disksave)
2197 {
2198 if (!for_disksave)
2199 {
2200 struct Lisp_Compiled_Function *cf =
2201 (struct Lisp_Compiled_Function *) header;
2202 if (cf->args_in_array)
2203 xfree (cf->args, Lisp_Object *);
2204 }
2205 }
2206
2207 DEFINE_BASIC_LISP_OBJECT ("compiled-function", compiled_function,
2208 mark_compiled_function,
2209 print_compiled_function,
2210 finalize_compiled_function,
2211 compiled_function_equal,
2212 compiled_function_hash,
2213 compiled_function_description,
2214 Lisp_Compiled_Function);
2215 #else /* not MC_ALLOC */
2216 DEFINE_BASIC_LISP_OBJECT ("compiled-function", compiled_function,
2217 mark_compiled_function, 2351 mark_compiled_function,
2218 print_compiled_function, 0, 2352 print_compiled_function, 0,
2219 compiled_function_equal, 2353 compiled_function_equal,
2220 compiled_function_hash, 2354 compiled_function_hash,
2221 compiled_function_description, 2355 compiled_function_description,
2222 Lisp_Compiled_Function); 2356 Lisp_Compiled_Function);
2223 #endif /* not MC_ALLOC */ 2357
2224 2358
2225 DEFUN ("compiled-function-p", Fcompiled_function_p, 1, 1, 0, /* 2359 DEFUN ("compiled-function-p", Fcompiled_function_p, 1, 1, 0, /*
2226 Return t if OBJECT is a byte-compiled function object. 2360 Return t if OBJECT is a byte-compiled function object.
2227 */ 2361 */
2228 (object)) 2362 (object))
2590 2724
2591 void 2725 void
2592 syms_of_bytecode (void) 2726 syms_of_bytecode (void)
2593 { 2727 {
2594 INIT_LISP_OBJECT (compiled_function); 2728 INIT_LISP_OBJECT (compiled_function);
2729 #ifdef NEW_GC
2730 INIT_LISP_OBJECT (compiled_function_args);
2731 #endif /* NEW_GC */
2595 2732
2596 DEFERROR_STANDARD (Qinvalid_byte_code, Qinvalid_state); 2733 DEFERROR_STANDARD (Qinvalid_byte_code, Qinvalid_state);
2597 DEFSYMBOL (Qbyte_code); 2734 DEFSYMBOL (Qbyte_code);
2598 DEFSYMBOL_MULTIWORD_PREDICATE (Qcompiled_functionp); 2735 DEFSYMBOL_MULTIWORD_PREDICATE (Qcompiled_functionp);
2599 2736