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
DEFINE_GOTO_TABLE(gDvmMterpHandlerNames)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 */
dvmMterpStdBail(MterpGlue * glue,bool changeInterp)76 void dvmMterpStdBail(MterpGlue* glue, bool changeInterp)
77 {
78 jmp_buf* pJmpBuf = glue->bailPtr;
79 longjmp(*pJmpBuf, ((int)changeInterp)+1);
80 }
81
82