blob: 4fe0d2cadb464492a96f7ed0975472a64295b57e [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
2 * Handler function table, one entry per opcode.
3 */
4#undef H
5#define H(_op) dvmMterp_##_op
6DEFINE_GOTO_TABLE(gDvmMterpHandlers)
7
8#undef H
9#define H(_op) #_op
10DEFINE_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 */
20bool 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) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080033 LOGVV("mterp threadid=%d returning %d\n",
Andy McFadden6e2af6d2011-02-14 14:04:42 -080034 dvmThreadSelf()->threadId, changeInterp);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080035 return changeInterp;
36 }
37
38 /*
39 * We may not be starting at a point where we're executing instructions.
40 * We need to pick up where the other interpreter left off.
41 *
42 * In some cases we need to call into a throw/return handler which
43 * will do some processing and then either return to us (updating "glue")
44 * or longjmp back out.
45 */
46 switch (glue->entryPoint) {
47 case kInterpEntryInstr:
48 /* just start at the start */
49 break;
50 case kInterpEntryReturn:
51 dvmMterp_returnFromMethod(glue);
52 break;
53 case kInterpEntryThrow:
54 dvmMterp_exceptionThrown(glue);
55 break;
56 default:
57 dvmAbort();
58 }
59
60 /* run until somebody longjmp()s out */
61 while (true) {
62 typedef void (*Handler)(MterpGlue* glue);
63
64 u2 inst = /*glue->*/pc[0];
65 Handler handler = (Handler) gDvmMterpHandlers[inst & 0xff];
Andy McFadden6e2af6d2011-02-14 14:04:42 -080066 (void) gDvmMterpHandlerNames; /* avoid gcc "defined but not used" */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080067 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 */
76void dvmMterpStdBail(MterpGlue* glue, bool changeInterp)
77{
78 jmp_buf* pJmpBuf = glue->bailPtr;
79 longjmp(*pJmpBuf, ((int)changeInterp)+1);
80}