Home | History | Annotate | Download | only in cstubs
      1 /*
      2  * Handler function table, one entry per opcode.
      3  */
      4 #undef H
      5 #define H(_op) dvmMterp_##_op
      6 DEFINE_GOTO_TABLE(gDvmMterpHandlers)
      7 
      8 #undef H
      9 #define H(_op) #_op
     10 DEFINE_GOTO_TABLE(gDvmMterpHandlerNames)
     11 
     12 #include <setjmp.h>
     13 
     14 /*
     15  * C mterp entry point.  This just calls the various C fallbacks, making
     16  * this a slow but portable interpeter.
     17  *
     18  * This is only used for the "allstubs" variant.
     19  */
     20 bool dvmMterpStdRun(MterpGlue* glue)
     21 {
     22     jmp_buf jmpBuf;
     23     int changeInterp;
     24 
     25     glue->bailPtr = &jmpBuf;
     26 
     27     /*
     28      * We want to return "changeInterp" as a boolean, but we can't return
     29      * zero through longjmp, so we return (boolean+1).
     30      */
     31     changeInterp = setjmp(jmpBuf) -1;
     32     if (changeInterp >= 0) {
     33         Thread* threadSelf = dvmThreadSelf();
     34         LOGVV("mterp threadid=%d returning %d\n",
     35             threadSelf->threadId, changeInterp);
     36         return changeInterp;
     37     }
     38 
     39     /*
     40      * We may not be starting at a point where we're executing instructions.
     41      * We need to pick up where the other interpreter left off.
     42      *
     43      * In some cases we need to call into a throw/return handler which
     44      * will do some processing and then either return to us (updating "glue")
     45      * or longjmp back out.
     46      */
     47     switch (glue->entryPoint) {
     48     case kInterpEntryInstr:
     49         /* just start at the start */
     50         break;
     51     case kInterpEntryReturn:
     52         dvmMterp_returnFromMethod(glue);
     53         break;
     54     case kInterpEntryThrow:
     55         dvmMterp_exceptionThrown(glue);
     56         break;
     57     default:
     58         dvmAbort();
     59     }
     60 
     61     /* run until somebody longjmp()s out */
     62     while (true) {
     63         typedef void (*Handler)(MterpGlue* glue);
     64 
     65         u2 inst = /*glue->*/pc[0];
     66         Handler handler = (Handler) gDvmMterpHandlers[inst & 0xff];
     67         LOGVV("handler %p %s\n",
     68             handler, (const char*) gDvmMterpHandlerNames[inst & 0xff]);
     69         (*handler)(glue);
     70     }
     71 }
     72 
     73 /*
     74  * C mterp exit point.  Call here to bail out of the interpreter.
     75  */
     76 void dvmMterpStdBail(MterpGlue* glue, bool changeInterp)
     77 {
     78     jmp_buf* pJmpBuf = glue->bailPtr;
     79     longjmp(*pJmpBuf, ((int)changeInterp)+1);
     80 }
     81