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