Annotation of 43BSD/contrib/emacs/src/bytecode.c, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.