home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / kaffe-0.5p4-src.tgz / tar.out / contrib / kaffe / kaffevm / intrp / machine.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  212 lines

  1. /*
  2.  * machine.c
  3.  * Java virtual machine interpreter.
  4.  *
  5.  * Copyright (c) 1996 Systems Architecture Research Centre,
  6.  *                 City University, London, UK.
  7.  *
  8.  * See the file "license.terms" for information on usage and redistribution
  9.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  *
  11.  * Written by Tim Wilkinson <tim@sarc.city.ac.uk>, May, June 1996.
  12.  */
  13.  
  14. #define    DBG(s)
  15. #define    RDBG(s)
  16. #define    NDBG(s)
  17. #define    IDBG(s)
  18.  
  19. #include "config.h"
  20. #include <stdio.h>
  21. #include <assert.h>
  22. #include <stdlib.h>
  23. #include <setjmp.h>
  24. #include <math.h>
  25. #if defined(HAVE_MALLOC_H)
  26. #include <malloc.h>
  27. #endif
  28. #include "gtypes.h"
  29. #include "bytecode.h"
  30. #include "slots.h"
  31. #include "machine.h"
  32. #include "icode.h"
  33. #include "access.h"
  34. #include "object.h"
  35. #include "constants.h"
  36. #include "classMethod.h"
  37. #include "lookup.h"
  38. #include "soft.h"
  39. #include "exception.h"
  40. #include "external.h"
  41. #include "baseClasses.h"
  42. #include "checks.h"
  43. #include "gc.h"
  44.  
  45. #define    define_insn(code)    break;                    \
  46.                 case code:                \
  47.                 IDBG( printf("%03d: %s\n", pc, #code); )
  48.  
  49. void unimp(void);
  50.  
  51. /*
  52.  * Length of each opcode.
  53.  */
  54. static uint8 oplen[256] = {
  55.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
  56.     2, 3, 2, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 
  57.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
  58.     1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 
  59.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
  60.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
  61.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
  62.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
  63.     1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
  64.     1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 
  65.     3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 0, 0, 1, 1, 1, 1, 
  66.     1, 1, 3, 3, 3, 3, 3, 3, 3, 5, 1, 3, 2, 3, 1, 1, 
  67.     3, 3, 1, 1, 2, 4, 3, 3, 5, 5, 1, 1, 1, 1, 1, 1, 
  68.     1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
  69.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
  70.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
  71. };
  72.  
  73. /* Call, field and creation information */
  74. callInfo cinfo;
  75. fieldInfo flinfo;
  76. createInfo crinfo;
  77. exceptionInfo info;
  78.  
  79. /* Misc machine variables */
  80. jint cc;
  81. jlong lcc;
  82. slots* cnst;
  83. slots tmp[1];
  84. slots tmp2[1];
  85. slots mtable[1];
  86.  
  87. /* Slot to store the return value */
  88. slots retarg[1];
  89.  
  90. /* Misc stuff */
  91. jmp_buf* cjbuf;
  92. object* exceptionObject;
  93.  
  94. #define    code    ((bytecode*)meth->code)
  95.  
  96. void
  97. virtualMachine(methods* meth, slots* arg)
  98. {
  99.     slots* lcl;
  100.     int sp;
  101.     uintp pc;
  102.     uintp npc;
  103.     object* mobj;
  104.  
  105.     jmp_buf mjbuf;
  106.     jmp_buf* pjbuf;
  107.  
  108.     /* Variables used directly in the machine */
  109.     uint16 wide;
  110.     int32 idx;
  111.     jint low;
  112.     jint high;
  113.  
  114.     /* If this is native, then call the real function */
  115.     if (meth->accflags & ACC_NATIVE) {
  116. NDBG(        printf("Call to native %s.%s%s.\n", meth->class->name, meth->pair->s1, meth->pair->s2); )
  117.         native(meth);
  118.         (*(void(*)(void*))meth->ncode)(arg);
  119.         return;
  120.     }
  121.  
  122.     /* Allocate stack space and locals. */
  123.     lcl = alloca(sizeof(slots) * (meth->localsz + meth->stacksz));
  124.  
  125.     mobj = 0;
  126.     pc = 0;
  127.     npc = 0;
  128.  
  129.     /* If we have any exception handlers we must prepare to catch them.
  130.      * We also need to catch if we are synchronised (so we can release it).
  131.      */
  132.     pjbuf = cjbuf;
  133.     if (meth->exception_table_len > 0 || (meth->accflags & ACC_SYNCHRONISED)) {
  134.         cjbuf = &mjbuf;
  135.         if (setjmp(mjbuf) != 0) {
  136.             /* Look for handler */
  137.             if (findExceptionBlockInMethod(pc, exceptionObject->dtable->class, meth, &info) == false) {
  138.                 /* If not here, exit monitor if synchronised. */
  139.                 if (mobj != 0) {
  140.                     soft_monitorexit(mobj);
  141.                 }
  142.                 /* Rethrow exception */
  143.                 cjbuf = pjbuf;
  144.                 throwException(exceptionObject);
  145.             }
  146.  
  147.             cjbuf = &mjbuf;
  148.             npc = info.handler;
  149.             sp = meth->stacksz - 1;
  150.             lcl[meth->localsz+sp].v.taddr = exceptionObject;
  151.             goto restart;
  152.         }
  153.     }
  154.  
  155.     /* Calculate number of arguments */
  156.     idx = meth->ins + (meth->accflags & ACC_STATIC ? 0 : 1);
  157.  
  158. DBG(    printf("Call to method %s.%s%s.\n", meth->class->name, meth->pair->s1, meth->pair->s2); )
  159.  
  160.     /* Copy in the arguments */
  161.     for (sp = 0; sp < idx; sp++) {
  162.         lcl[sp] = arg[idx - sp - 1];
  163.     }
  164.     /* And zero the rest */
  165.     for(; sp < meth->localsz; sp++) {
  166.         lcl[sp].v.tint = 0;
  167.     }
  168.  
  169.     /* Sync. if required */
  170.     if (meth->accflags & ACC_SYNCHRONISED) { 
  171.         if (meth->accflags & ACC_STATIC) {
  172.             mobj = &meth->class->head;
  173.         }
  174.         else {
  175.             mobj = (object*)lcl[0].v.taddr;
  176.         }
  177.         soft_monitorenter(mobj);
  178.     }       
  179.  
  180.     sp = meth->stacksz;
  181.  
  182.     restart:
  183.     wide = 0;
  184.  
  185.     /* Finally we get to actually execute the machine */
  186.     for (;;) {
  187.         assert(npc < meth->codelen);
  188.         pc = npc;
  189.         npc = pc + oplen[code[pc]];
  190.         switch (code[pc]) {
  191.         default:
  192.             unimp();
  193. #include "kaffe.def"
  194.         }
  195.     }
  196.     end:
  197.  
  198.     /* Unsync. if required */
  199.     if (mobj != 0) {
  200.         soft_monitorexit(mobj);
  201.     }       
  202.     cjbuf = pjbuf;
  203.  
  204. RDBG(    printf("Returning from method %s%s.\n", meth->pair->s1, meth->pair->s2); )
  205. }
  206.  
  207. void
  208. unimp(void)
  209. {
  210.     assert("Unimplemented VM function" == 0);
  211. }
  212.