|
|
1.1 ! root 1: /* Execution of byte code produced by bytecomp.el. ! 2: Copyright (C) 1985 Richard M. Stallman. ! 3: ! 4: This file is part of GNU Emacs. ! 5: ! 6: GNU Emacs is distributed in the hope that it will be useful, ! 7: but WITHOUT ANY WARRANTY. No author or distributor ! 8: accepts responsibility to anyone for the consequences of using it ! 9: or for whether it serves any particular purpose or works at all, ! 10: unless he says so in writing. Refer to the GNU Emacs General Public ! 11: License for full details. ! 12: ! 13: Everyone is granted permission to copy, modify and redistribute ! 14: GNU Emacs, but only under the conditions described in the ! 15: GNU Emacs General Public License. A copy of this license is ! 16: supposed to have been given to you along with GNU Emacs so you ! 17: can know your rights and responsibilities. It should be in a ! 18: file named COPYING. Among other things, the copyright notice ! 19: and this notice must be preserved on all copies. */ ! 20: ! 21: ! 22: #include "config.h" ! 23: #include "lisp.h" ! 24: #include "buffer.h" ! 25: ! 26: Lisp_Object Qbytecode; ! 27: ! 28: /* Byte codes: */ ! 29: ! 30: #define Bvarref 010 ! 31: #define Bvarset 020 ! 32: #define Bvarbind 030 ! 33: #define Bcall 040 ! 34: #define Bunbind 050 ! 35: ! 36: #define Bnth 070 ! 37: #define Bsymbolp 071 ! 38: #define Bconsp 072 ! 39: #define Bstringp 073 ! 40: #define Blistp 074 ! 41: #define Beq 075 ! 42: #define Bmemq 076 ! 43: #define Bnot 077 ! 44: #define Bcar 0100 ! 45: #define Bcdr 0101 ! 46: #define Bcons 0102 ! 47: #define Blist1 0103 ! 48: #define Blist2 0104 ! 49: #define Blist3 0105 ! 50: #define Blist4 0106 ! 51: #define Blength 0107 ! 52: #define Baref 0110 ! 53: #define Baset 0111 ! 54: #define Bsymbol_value 0112 ! 55: #define Bsymbol_function 0113 ! 56: #define Bset 0114 ! 57: #define Bfset 0115 ! 58: #define Bget 0116 ! 59: #define Bsubstring 0117 ! 60: #define Bconcat2 0120 ! 61: #define Bconcat3 0121 ! 62: #define Bconcat4 0122 ! 63: #define Bsub1 0123 ! 64: #define Badd1 0124 ! 65: #define Beqlsign 0125 ! 66: #define Bgtr 0126 ! 67: #define Blss 0127 ! 68: #define Bleq 0130 ! 69: #define Bgeq 0131 ! 70: #define Bdiff 0132 ! 71: #define Bnegate 0133 ! 72: #define Bplus 0134 ! 73: #define Bmax 0135 ! 74: #define Bmin 0136 ! 75: ! 76: #define Bpoint 0140 ! 77: #define Bmark 0141 ! 78: #define Bgoto_char 0142 ! 79: #define Binsert 0143 ! 80: #define Bpoint_max 0144 ! 81: #define Bpoint_min 0145 ! 82: #define Bchar_after 0146 ! 83: #define Bfollowing_char 0147 ! 84: #define Bpreceding_char 0150 ! 85: #define Bcurrent_column 0151 ! 86: #define Bindent_to 0152 ! 87: #define Bscan_buffer 0153 ! 88: #define Beolp 0154 ! 89: #define Beobp 0155 ! 90: #define Bbolp 0156 ! 91: #define Bbobp 0157 ! 92: #define Bcurrent_buffer 0160 ! 93: #define Bset_buffer 0161 ! 94: #define Bread_char 0162 ! 95: #define Bset_mark 0163 ! 96: #define Binteractive_p 0164 /* Needed since interactive-p takes unevalled args */ ! 97: ! 98: #define Bconstant2 0201 ! 99: #define Bgoto 0202 ! 100: #define Bgotoifnil 0203 ! 101: #define Bgotoifnonnil 0204 ! 102: #define Bgotoifnilelsepop 0205 ! 103: #define Bgotoifnonnilelsepop 0206 ! 104: #define Breturn 0207 ! 105: #define Bdiscard 0210 ! 106: #define Bdup 0211 ! 107: ! 108: #define Bsave_excursion 0212 ! 109: #define Bsave_window_excursion 0213 ! 110: #define Bsave_restriction 0214 ! 111: #define Bcatch 0215 ! 112: ! 113: #define Bunwind_protect 0216 ! 114: #define Bcondition_case 0217 ! 115: #define Btemp_output_buffer_setup 0220 ! 116: #define Btemp_output_buffer_show 0221 ! 117: ! 118: #define Bconstant 0300 ! 119: #define CONSTANTLIM 0100 ! 120: ! 121: /* Fetch the next byte from the bytecode stream */ ! 122: ! 123: #define FETCH ((unsigned char *)XSTRING (bytestr)->data)[pc++] ! 124: ! 125: /* Fetch two bytes from the bytecode stream ! 126: and make a 16-bit number out of them */ ! 127: ! 128: #define FETCH2 (op = FETCH, op + (FETCH << 8)) ! 129: ! 130: /* Push x onto the execution stack. */ ! 131: ! 132: #define PUSH(x) (*++stackp = (x)) ! 133: ! 134: /* Pop a value off the execution stack. */ ! 135: ! 136: #define POP (*stackp--) ! 137: ! 138: /* Discard n values from the execution stack. */ ! 139: ! 140: #define DISCARD(n) (stackp -= (n)) ! 141: ! 142: /* Get the value which is at the top of the execution stack, but don't pop it. */ ! 143: ! 144: #define TOP (*stackp) ! 145: ! 146: ! 147: DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0, ! 148: "") ! 149: (bytestr, vector, maxdepth) ! 150: Lisp_Object bytestr, vector, maxdepth; ! 151: { ! 152: struct gcpro gcpro1, gcpro2, gcpro3; ! 153: int count = specpdl_ptr - specpdl; ! 154: register int pc = 0; ! 155: register int op; ! 156: Lisp_Object *stack; ! 157: register Lisp_Object *stackp; ! 158: Lisp_Object *stacke; ! 159: register Lisp_Object v1, v2; ! 160: Lisp_Object *vectorp = XVECTOR (vector)->contents; ! 161: ! 162: CHECK_STRING (bytestr, 0); ! 163: if (XTYPE (vector) != Lisp_Vector) ! 164: vector = wrong_type_argument (Qvectorp, vector); ! 165: CHECK_NUMBER (maxdepth, 2); ! 166: ! 167: stackp = (Lisp_Object *) alloca (XFASTINT (maxdepth) * sizeof (Lisp_Object)); ! 168: bzero (stackp, XFASTINT (maxdepth) * sizeof (Lisp_Object)); ! 169: GCPRO3 (bytestr, vector, *stackp); ! 170: gcpro3.nvars = XFASTINT (maxdepth); ! 171: ! 172: --stackp; ! 173: stack = stackp; ! 174: stacke = stackp + XFASTINT (maxdepth); ! 175: ! 176: while (1) ! 177: { ! 178: if (stackp > stacke) ! 179: error ("Stack overflow in byte code (byte compiler bug!)"); ! 180: if (stackp < stack) ! 181: error ("Stack underflow in byte code (byte compiler bug!)"); ! 182: switch (op = FETCH) ! 183: { ! 184: case Bvarref: case Bvarref+1: case Bvarref+2: case Bvarref+3: ! 185: case Bvarref+4: case Bvarref+5: ! 186: PUSH (Fsymbol_value (vectorp[op - Bvarref])); ! 187: break; ! 188: ! 189: case Bvarref+6: ! 190: PUSH (Fsymbol_value (vectorp[FETCH])); ! 191: break; ! 192: ! 193: case Bvarref+7: ! 194: PUSH (Fsymbol_value (vectorp[FETCH2])); ! 195: break; ! 196: ! 197: case Bvarset: case Bvarset+1: case Bvarset+2: case Bvarset+3: ! 198: case Bvarset+4: case Bvarset+5: ! 199: Fset (vectorp[op - Bvarset], POP); ! 200: break; ! 201: ! 202: case Bvarset+6: ! 203: Fset (vectorp[FETCH], POP); ! 204: break; ! 205: ! 206: case Bvarset+7: ! 207: Fset (vectorp[FETCH2], POP); ! 208: break; ! 209: ! 210: case Bvarbind: case Bvarbind+1: case Bvarbind+2: case Bvarbind+3: ! 211: case Bvarbind+4: case Bvarbind+5: ! 212: specbind (vectorp[op - Bvarbind], POP); ! 213: break; ! 214: ! 215: case Bvarbind+6: ! 216: specbind (vectorp[FETCH], POP); ! 217: break; ! 218: ! 219: case Bvarbind+7: ! 220: specbind (vectorp[FETCH2], POP); ! 221: break; ! 222: ! 223: case Bcall: case Bcall+1: case Bcall+2: case Bcall+3: ! 224: case Bcall+4: case Bcall+5: ! 225: op -= Bcall; ! 226: docall: ! 227: DISCARD(op); ! 228: gcpro3.nvars = &TOP - stack; ! 229: TOP = Ffuncall (op + 1, &TOP); ! 230: gcpro3.nvars = XFASTINT (maxdepth); ! 231: break; ! 232: ! 233: case Bcall+6: ! 234: op = FETCH; ! 235: goto docall; ! 236: ! 237: case Bcall+7: ! 238: op = FETCH2; ! 239: goto docall; ! 240: ! 241: case Bunbind: case Bunbind+1: case Bunbind+2: case Bunbind+3: ! 242: case Bunbind+4: case Bunbind+5: ! 243: unbind_to (specpdl_ptr - specpdl - (op - Bunbind)); ! 244: break; ! 245: ! 246: case Bunbind+6: ! 247: unbind_to (specpdl_ptr - specpdl - FETCH); ! 248: break; ! 249: ! 250: case Bunbind+7: ! 251: unbind_to (specpdl_ptr - specpdl - FETCH2); ! 252: break; ! 253: ! 254: case Bgoto: ! 255: QUIT; ! 256: op = FETCH2; /* pc = FETCH2 loses since FETCH2 contains pc++ */ ! 257: pc = op; ! 258: break; ! 259: ! 260: case Bgotoifnil: ! 261: QUIT; ! 262: op = FETCH2; ! 263: if (NULL (POP)) ! 264: pc = op; ! 265: break; ! 266: ! 267: case Bgotoifnonnil: ! 268: QUIT; ! 269: op = FETCH2; ! 270: if (!NULL (POP)) ! 271: pc = op; ! 272: break; ! 273: ! 274: case Bgotoifnilelsepop: ! 275: QUIT; ! 276: op = FETCH2; ! 277: if (NULL (TOP)) ! 278: pc = op; ! 279: else DISCARD(1); ! 280: break; ! 281: ! 282: case Bgotoifnonnilelsepop: ! 283: QUIT; ! 284: op = FETCH2; ! 285: if (!NULL (TOP)) ! 286: pc = op; ! 287: else DISCARD(1); ! 288: break; ! 289: ! 290: case Breturn: ! 291: v1 = POP; ! 292: goto exit; ! 293: ! 294: case Bdiscard: ! 295: DISCARD(1); ! 296: break; ! 297: ! 298: case Bdup: ! 299: v1 = TOP; ! 300: PUSH (v1); ! 301: break; ! 302: ! 303: case Bconstant2: ! 304: PUSH (vectorp[FETCH2]); ! 305: break; ! 306: ! 307: case Bsave_excursion: ! 308: record_unwind_protect (save_excursion_restore, save_excursion_save ()); ! 309: break; ! 310: ! 311: case Bsave_window_excursion: ! 312: TOP = Fsave_window_excursion (TOP); ! 313: break; ! 314: ! 315: case Bsave_restriction: ! 316: record_unwind_protect (save_restriction_restore, save_restriction_save ()); ! 317: break; ! 318: ! 319: case Bcatch: ! 320: v1 = POP; ! 321: TOP = internal_catch (TOP, Feval, v1); ! 322: break; ! 323: ! 324: case Bunwind_protect: ! 325: record_unwind_protect (0, POP); ! 326: (specpdl_ptr - 1)->symbol = Qnil; ! 327: break; ! 328: ! 329: case Bcondition_case: ! 330: v1 = POP; ! 331: v1 = Fcons (POP, v1); ! 332: TOP = Fcondition_case (Fcons (TOP, v1)); ! 333: break; ! 334: ! 335: case Btemp_output_buffer_setup: ! 336: temp_output_buffer_setup (XSTRING (TOP)->data); ! 337: TOP = Vstandard_output; ! 338: break; ! 339: ! 340: case Btemp_output_buffer_show: ! 341: v1 = POP; ! 342: temp_output_buffer_show (TOP); ! 343: TOP = v1; ! 344: break; ! 345: ! 346: case Bnth: ! 347: v1 = POP; ! 348: v2 = TOP; ! 349: CHECK_NUMBER (v2, 0); ! 350: op = XINT (v2); ! 351: while (--op >= 0) ! 352: { ! 353: if (LISTP (v1)) ! 354: v1 = XCONS (v1)->cdr; ! 355: else if (!NULL (v1)) ! 356: { ! 357: v1 = wrong_type_argument (Qlistp, v1); ! 358: op++; ! 359: } ! 360: } ! 361: goto docar; ! 362: ! 363: case Bsymbolp: ! 364: TOP = XTYPE (TOP) == Lisp_Symbol ? Qt : Qnil; ! 365: break; ! 366: ! 367: case Bconsp: ! 368: TOP = LISTP (TOP) ? Qt : Qnil; ! 369: break; ! 370: ! 371: case Bstringp: ! 372: TOP = XTYPE (TOP) == Lisp_String ? Qt : Qnil; ! 373: break; ! 374: ! 375: case Blistp: ! 376: TOP = LISTP (TOP) || NULL (TOP) ? Qt : Qnil; ! 377: break; ! 378: ! 379: case Beq: ! 380: v1 = POP; ! 381: TOP = EQ (v1, TOP) ? Qt : Qnil; ! 382: break; ! 383: ! 384: case Bmemq: ! 385: v1 = POP; ! 386: TOP = Fmemq (TOP, v1); ! 387: break; ! 388: ! 389: case Bnot: ! 390: TOP = NULL (TOP) ? Qt : Qnil; ! 391: break; ! 392: ! 393: case Bcar: ! 394: v1 = TOP; ! 395: docar: ! 396: if (LISTP (v1)) TOP = XCONS (v1)->car; ! 397: else if (NULL (v1)) TOP = Qnil; ! 398: else Fcar (wrong_type_argument (Qlistp, v1)); ! 399: break; ! 400: ! 401: case Bcdr: ! 402: v1 = TOP; ! 403: if (LISTP (v1)) TOP = XCONS (v1)->cdr; ! 404: else if (NULL (v1)) TOP = Qnil; ! 405: else Fcdr (wrong_type_argument (Qlistp, v1)); ! 406: break; ! 407: ! 408: case Bcons: ! 409: v1 = POP; ! 410: TOP = Fcons (TOP, v1); ! 411: break; ! 412: ! 413: case Blist1: ! 414: TOP = Fcons (TOP, Qnil); ! 415: break; ! 416: ! 417: case Blist2: ! 418: v1 = POP; ! 419: TOP = Fcons (TOP, Fcons (v1, Qnil)); ! 420: break; ! 421: ! 422: case Blist3: ! 423: DISCARD(2); ! 424: TOP = Flist (3, &TOP); ! 425: break; ! 426: ! 427: case Blist4: ! 428: DISCARD(3); ! 429: TOP = Flist (4, &TOP); ! 430: break; ! 431: ! 432: case Blength: ! 433: TOP = Flength (TOP); ! 434: break; ! 435: ! 436: case Baref: ! 437: v1 = POP; ! 438: TOP = Faref (TOP, v1); ! 439: break; ! 440: ! 441: case Baset: ! 442: v2 = POP; v1 = POP; ! 443: TOP = Faset (TOP, v1, v2); ! 444: break; ! 445: ! 446: case Bsymbol_value: ! 447: TOP = Fsymbol_value (TOP); ! 448: break; ! 449: ! 450: case Bsymbol_function: ! 451: TOP = Fsymbol_function (TOP); ! 452: break; ! 453: ! 454: case Bset: ! 455: v1 = POP; ! 456: TOP = Fset (TOP, v1); ! 457: break; ! 458: ! 459: case Bfset: ! 460: v1 = POP; ! 461: TOP = Ffset (TOP, v1); ! 462: break; ! 463: ! 464: case Bget: ! 465: v1 = POP; ! 466: TOP = Fget (TOP, v1); ! 467: break; ! 468: ! 469: case Bsubstring: ! 470: v2 = POP; v1 = POP; ! 471: TOP = Fsubstring (TOP, v1, v2); ! 472: break; ! 473: ! 474: case Bconcat2: ! 475: DISCARD(1); ! 476: TOP = Fconcat (2, &TOP); ! 477: break; ! 478: ! 479: case Bconcat3: ! 480: DISCARD(2); ! 481: TOP = Fconcat (3, &TOP); ! 482: break; ! 483: ! 484: case Bconcat4: ! 485: DISCARD(3); ! 486: TOP = Fconcat (4, &TOP); ! 487: break; ! 488: ! 489: case Bsub1: ! 490: v1 = TOP; ! 491: if (XTYPE (v1) == Lisp_Int) ! 492: { ! 493: XSETINT (v1, XINT (v1) - 1); ! 494: TOP = v1; ! 495: } ! 496: else ! 497: TOP = Fsub1 (v1); ! 498: break; ! 499: ! 500: case Badd1: ! 501: v1 = TOP; ! 502: if (XTYPE (v1) == Lisp_Int) ! 503: { ! 504: XSETINT (v1, XINT (v1) + 1); ! 505: TOP = v1; ! 506: } ! 507: else ! 508: TOP = Fadd1 (v1); ! 509: break; ! 510: ! 511: case Beqlsign: ! 512: v2 = POP; v1 = TOP; ! 513: CHECK_NUMBER_COERCE_MARKER (v1, 0); ! 514: CHECK_NUMBER_COERCE_MARKER (v2, 0); ! 515: TOP = XINT (v1) == XINT (v2) ? Qt : Qnil; ! 516: break; ! 517: ! 518: case Bgtr: ! 519: v1 = POP; ! 520: TOP = Fgtr (TOP, v1); ! 521: break; ! 522: ! 523: case Blss: ! 524: v1 = POP; ! 525: TOP = Flss (TOP, v1); ! 526: break; ! 527: ! 528: case Bleq: ! 529: v1 = POP; ! 530: TOP = Fleq (TOP, v1); ! 531: break; ! 532: ! 533: case Bgeq: ! 534: v1 = POP; ! 535: TOP = Fgeq (TOP, v1); ! 536: break; ! 537: ! 538: case Bdiff: ! 539: DISCARD(1); ! 540: TOP = Fminus (2, &TOP); ! 541: break; ! 542: ! 543: case Bnegate: ! 544: v1 = TOP; ! 545: if (XTYPE (v1) == Lisp_Int) ! 546: { ! 547: XSETINT (v1, - XINT (v1)); ! 548: TOP = v1; ! 549: } ! 550: else ! 551: TOP = Fminus (1, &TOP); ! 552: break; ! 553: ! 554: case Bplus: ! 555: DISCARD(1); ! 556: TOP = Fplus (2, &TOP); ! 557: break; ! 558: ! 559: case Bmax: ! 560: DISCARD(1); ! 561: TOP = Fmax (2, &TOP); ! 562: break; ! 563: ! 564: case Bmin: ! 565: DISCARD(1); ! 566: TOP = Fmin (2, &TOP); ! 567: break; ! 568: ! 569: case Bpoint: ! 570: XFASTINT (v1) = point; ! 571: PUSH (v1); ! 572: break; ! 573: ! 574: case Bmark: ! 575: PUSH (Fmark ()); ! 576: break; ! 577: ! 578: case Bgoto_char: ! 579: TOP = Fgoto_char (TOP); ! 580: break; ! 581: ! 582: case Binsert: ! 583: TOP = Finsert (1, &TOP); ! 584: break; ! 585: ! 586: case Bpoint_max: ! 587: XFASTINT (v1) = NumCharacters+1; ! 588: PUSH (v1); ! 589: break; ! 590: ! 591: case Bpoint_min: ! 592: XFASTINT (v1) = FirstCharacter; ! 593: PUSH (v1); ! 594: break; ! 595: ! 596: case Bchar_after: ! 597: TOP = Fchar_after (TOP); ! 598: break; ! 599: ! 600: case Bfollowing_char: ! 601: XFASTINT (v1) = point>NumCharacters ? 0 : CharAt(point); ! 602: PUSH (v1); ! 603: break; ! 604: ! 605: case Bpreceding_char: ! 606: XFASTINT (v1) = point<=FirstCharacter ? 0 : CharAt(point-1); ! 607: PUSH (v1); ! 608: break; ! 609: ! 610: case Bcurrent_column: ! 611: XFASTINT (v1) = current_column (); ! 612: PUSH (v1); ! 613: break; ! 614: ! 615: case Bindent_to: ! 616: TOP = Findent_to (TOP, Qnil); ! 617: break; ! 618: ! 619: case Bscan_buffer: ! 620: v2 = POP; v1 = POP; ! 621: TOP = Fscan_buffer (TOP, v1, v2); ! 622: break; ! 623: ! 624: case Beolp: ! 625: PUSH (Feolp ()); ! 626: break; ! 627: ! 628: case Beobp: ! 629: PUSH (Feobp ()); ! 630: break; ! 631: ! 632: case Bbolp: ! 633: PUSH (Fbolp ()); ! 634: break; ! 635: ! 636: case Bbobp: ! 637: PUSH (Fbobp ()); ! 638: break; ! 639: ! 640: case Bcurrent_buffer: ! 641: PUSH (Fcurrent_buffer ()); ! 642: break; ! 643: ! 644: case Bset_buffer: ! 645: TOP = Fset_buffer (TOP); ! 646: break; ! 647: ! 648: case Bread_char: ! 649: PUSH (Fread_char ()); ! 650: QUIT; ! 651: break; ! 652: ! 653: case Bset_mark: ! 654: TOP = Fset_mark (TOP); ! 655: break; ! 656: ! 657: case Binteractive_p: ! 658: PUSH (Finteractive_p ()); ! 659: break; ! 660: ! 661: default: ! 662: if ((op -= Bconstant) < (unsigned)CONSTANTLIM) ! 663: PUSH (vectorp[op]); ! 664: } ! 665: } ! 666: ! 667: exit: ! 668: UNGCPRO; ! 669: unbind_to (count); ! 670: return v1; ! 671: } ! 672: ! 673: syms_of_bytecode () ! 674: { ! 675: Qbytecode = intern ("byte-code"); ! 676: staticpro (&Qbytecode); ! 677: ! 678: defsubr (&Sbyte_code); ! 679: } ! 680:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.