blob: 58add85212f4283a9da558bb10e4d13bd5c93754 [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 */
buzbee9f601a92011-02-11 17:48:20 -080020bool dvmMterpStdRun(Thread* self)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080021{
22 jmp_buf jmpBuf;
23 int changeInterp;
24
buzbee9f601a92011-02-11 17:48:20 -080025 self->bailPtr = &jmpBuf;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080026
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
buzbee9f601a92011-02-11 17:48:20 -080043 * will do some processing and then either return to us (updating "self")
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080044 * or longjmp back out.
45 */
buzbee9f601a92011-02-11 17:48:20 -080046 switch (self->entryPoint) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080047 case kInterpEntryInstr:
48 /* just start at the start */
49 break;
50 case kInterpEntryReturn:
buzbee9f601a92011-02-11 17:48:20 -080051 dvmMterp_returnFromMethod(self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080052 break;
53 case kInterpEntryThrow:
buzbee9f601a92011-02-11 17:48:20 -080054 dvmMterp_exceptionThrown(self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080055 break;
56 default:
57 dvmAbort();
58 }
59
60 /* run until somebody longjmp()s out */
61 while (true) {
buzbee9f601a92011-02-11 17:48:20 -080062 typedef void (*Handler)(Thread* self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080063
buzbee9f601a92011-02-11 17:48:20 -080064 u2 inst = /*self->*/pc[0];
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080065 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]);
buzbee9f601a92011-02-11 17:48:20 -080069 (*handler)(self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080070 }
71}
72
73/*
74 * C mterp exit point. Call here to bail out of the interpreter.
75 */
buzbee9f601a92011-02-11 17:48:20 -080076void dvmMterpStdBail(Thread* self, bool changeInterp)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080077{
buzbee9f601a92011-02-11 17:48:20 -080078 jmp_buf* pJmpBuf = self->bailPtr;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080079 longjmp(*pJmpBuf, ((int)changeInterp)+1);
80}