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 / lookup.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  9KB  |  360 lines

  1. /*
  2.  * lookup.c
  3.  * Various lookup calls for resolving objects, methods, exceptions, etc.
  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>, February 1996.
  12.  */
  13.  
  14. #define DBG(s)
  15. #define FDBG(s)
  16. #define EDBG(s)
  17.  
  18. #include <stdio.h>
  19. #include <assert.h>
  20. #include <stdlib.h>
  21. #include "gtypes.h"
  22. #include "errors.h"
  23. #include "slots.h"
  24. #include "access.h"
  25. #include "object.h"
  26. #include "constants.h"
  27. #include "classMethod.h"
  28. #include "lookup.h"
  29. #include "exception.h"
  30. #include "thread.h"
  31. #include "baseClasses.h"
  32. #include "machine.h"
  33.  
  34. extern strpair* initpair;
  35. extern methods* methodList;
  36. extern classes* ObjectClass;
  37.  
  38. /*
  39.  * Lookup a method reference and get the various interesting bits.
  40.  */
  41. void
  42. getMethodSignatureClass(constIndex idx, constants* pool, callInfo* call)
  43. {
  44.     constIndex ci;
  45.     constIndex ni;
  46.     constIndex nin;
  47.     constIndex nis;
  48.     createInfo cls;
  49.     strpair* pair;
  50.     char* s;
  51.     int i;
  52.     int r;
  53.         methods* mptr;
  54.         classes* cptr;
  55.  
  56.     if (pool->tags[idx] != CONSTANT_Methodref &&
  57.         pool->tags[idx] != CONSTANT_InterfaceMethodref) {
  58. DBG(        printf("No Methodref found\n");                )
  59.                 throwException(NoSuchMethodError);
  60.     }
  61.  
  62.     ni = METHODREF_NAMEANDTYPE(idx, pool);
  63.     if (pool->tags[ni] != CONSTANT_NameAndType) {
  64. DBG(        printf("No Methodref:NameAndType found\n");        )
  65.                 throwException(NoSuchMethodError);
  66.     }
  67.     nin = NAMEANDTYPE_NAME(ni, pool);
  68.     if (pool->tags[nin] != CONSTANT_Utf8) {
  69. DBG(        printf("No Methodref:NameAndType:Utf8 found\n");    )
  70.                 throwException(NoSuchMethodError);
  71.     }
  72.     nis = NAMEANDTYPE_SIGNATURE(ni, pool);
  73.     if (pool->tags[nis] != CONSTANT_Utf8) {
  74. DBG(        printf("No Methodref:NameAndType:Utf8 found\n");    )
  75.                 throwException(NoSuchMethodError);
  76.     }
  77.  
  78.     ci = METHODREF_CLASS(idx, pool);
  79.     if (pool->tags[ci] != CONSTANT_Class) {
  80. DBG(        printf("No Methodref:Class found\n");            )
  81.                 throwException(NoSuchMethodError);
  82.     }
  83.     getClass(ci, pool, &cls);
  84.  
  85. DBG(    printf("lookupMethodSignatureClass(%s,%s,%s)\n",
  86.         cls.class->name, pool->data[nin], pool->data[nis]);    )
  87.  
  88.     /*
  89.      * We now have a complete class and method signature.  We can
  90.      * Now work out some things we might need to know, like no. of
  91.      * arguments, address of function, etc.
  92.      */
  93.     countInsAndOuts(pool->data[nis].v.tstr, &call->in, &call->out, &call->rettype);
  94. DBG(    printf("in = %d, out = %d\n", call->in, call->out);        )
  95.     pair = lookupStringPair(pool->data[nin].v.tstr, pool->data[nis].v.tstr);
  96.     assert(pair != 0);
  97.     call->mtag = (int)pair;
  98.     call->offset = pair->hash % MAXMETHOD;
  99.     call->dtable = cls.class->dtable;
  100.  
  101.     /* Find method */
  102.         for (cptr = cls.class; cptr != 0; cptr = cptr->superclass) {
  103.                 for (mptr = cptr->methodList; mptr != 0; mptr = mptr->next) {
  104.                         if (mptr->pair == pair) {
  105.                 goto foundit;
  106.             }
  107.         }
  108.     }
  109.     assert("Method not found" == 0);
  110.     foundit:
  111.     call->idx = mptr->idx;
  112.  
  113.     /* Generate a short signature - used by calls */
  114.     if (call->type != 0) {
  115.         free(call->type);
  116.     }
  117.     if (call->in == 0) {
  118.         call->type = 0;
  119.     }
  120.     else {
  121.         call->type = malloc(call->in);
  122.         assert(call->type != 0);
  123.         s = pool->data[nis].v.tstr;
  124.         i = 0;
  125.         while (i < call->in) {
  126.             r = sizeofSigItem(&s, &call->type[i]);
  127.             if (r == -1) {
  128.                 break;
  129.             }
  130.             else if (r == 2) {
  131.                 call->type[i+1] = call->type[i];
  132.             }
  133.             i += r;
  134.         }
  135.     }
  136. }
  137.  
  138. void
  139. getClass(constIndex idx, constants* pool, createInfo* create)
  140. {
  141.     constIndex cs;
  142.     classes* class;
  143.     char* cname;
  144.  
  145.     if (pool->tags[idx] != CONSTANT_Class) {
  146. DBG(        printf("No Class found\n");                )
  147.                 throwException(ClassNotFoundException);
  148.     }
  149.  
  150.     cs = CLASS_NAME(idx, pool);
  151.     if (pool->tags[cs] != CONSTANT_Utf8) {
  152. DBG(        printf("No Class:Utf8 found\n");            )
  153.                 throwException(ClassNotFoundException);
  154.     }
  155.     cname = pool->data[cs].v.tstr;
  156.  
  157. DBG(    printf("Class name %s\n", cname);                )
  158.  
  159.     /* If an array, then treat as an array */
  160.     if (cname[0] == '[') {
  161.         class = lookupArray(cname);
  162.     }
  163.     else {
  164.         /* Lookup class */
  165.         class = lookupClass(cname);
  166.     }
  167.     if (class == 0) {
  168. DBG(        printf("Class %s not loaded.\n", cname);    )
  169.                 throwException(ClassNotFoundException);
  170.     }
  171.  
  172.     create->class = class;
  173. }
  174.  
  175. void
  176. getField(constIndex idx, bool isStatic, constants* pool, fieldInfo* fld)
  177. {
  178.     constIndex ci;
  179.     constIndex ni;
  180.     constIndex cis;
  181.     constIndex nin;
  182.     constIndex nis;
  183.     fields* field;
  184.  
  185.     if (pool->tags[idx] != CONSTANT_Fieldref) {
  186. FDBG(        printf("No Fieldref found\n");                )
  187.                 throwException(NoSuchFieldError);
  188.     }
  189.  
  190.     ci = FIELDREF_CLASS(idx, pool);
  191.     if (pool->tags[ci] != CONSTANT_Class) {
  192. FDBG(        printf("No Methodref:Class found\n");            )
  193.                 throwException(NoSuchFieldError);
  194.     }
  195.     ni = FIELDREF_NAMEANDTYPE(idx, pool);
  196.     if (pool->tags[ni] != CONSTANT_NameAndType) {
  197. FDBG(        printf("No Methodref:NameAndType found\n");        )
  198.                 throwException(NoSuchFieldError);
  199.     }
  200.  
  201.     cis = CLASS_NAME(ci, pool);
  202.     if (pool->tags[cis] != CONSTANT_Utf8) {
  203. FDBG(        printf("No Methodref:Class:Utf8 found\n");        )
  204.                 throwException(NoSuchFieldError);
  205.     }
  206.  
  207.     nin = NAMEANDTYPE_NAME(ni, pool);
  208.     if (pool->tags[nin] != CONSTANT_Utf8) {
  209. FDBG(        printf("No Methodref:NameAndType:Utf8 found\n");    )
  210.                 throwException(NoSuchFieldError);
  211.     }
  212.     nis = NAMEANDTYPE_SIGNATURE(ni, pool);
  213.     if (pool->tags[nis] != CONSTANT_Utf8) {
  214. FDBG(        printf("No Methodref:NameAndType:Utf8 found\n");    )
  215.                 throwException(NoSuchFieldError);
  216.     }
  217.  
  218. FDBG(    printf("*** getField(%s,%s,%s)\n",
  219.         pool->data[cis], pool->data[nin], pool->data[nis]);    )
  220.  
  221.     field = lookupClassField(pool->data[cis].v.tstr, pool->data[nin].v.tstr, isStatic);
  222.     if (field == 0) {
  223. FDBG(        printf("Field not found\n");                )
  224.                 throwException(NoSuchFieldError);
  225.     }
  226.  
  227.     fld->class = field->class;
  228.     fld->size = field->size;
  229.     fld->offset = field->offset;
  230.     if (field->sig[0] == 'L' || field->sig[0] == '[') {
  231.         fld->isref = true;
  232.     }
  233.     else {
  234.         fld->isref = false;
  235.     }
  236.  
  237. FDBG(    printf("class=%s, classsize=%d, fldsize=%d, fldoffset=%d\n",
  238.         fld->class->name, fld->class->fsize,
  239.         fld->size, fld->offset);                )
  240. }
  241.  
  242. /*
  243.  * Lookup a method (and translate) in the specified class.
  244.  */
  245. methods*
  246. findMethod(classes* class, strpair* pair)
  247. {
  248.     methods* mptr;
  249.  
  250.     /*
  251.      * Lookup method - this could be alot more efficient but never mind.
  252.      * Also there is no attempt to honour PUBLIC, PRIVATE, etc.
  253.      */
  254.     for (; class != 0; class = class->superclass) {
  255.         for (mptr = class->methodList; mptr != 0; mptr = mptr->next) {
  256.             if (mptr->pair == pair) {
  257. #if defined(TRANSLATOR)
  258.                 /*
  259.                  * Generate code on demand.
  260.                  */
  261.                 if (mptr->ncode == 0) {
  262.                     intsDisable();
  263.                     translate(mptr);
  264.                     initClasses();
  265.                     intsRestore();
  266.                 }
  267. #endif
  268.                 return (mptr);
  269.             }
  270.         }
  271.     }
  272.     return (0);
  273. }
  274.  
  275. #if defined(TRANSLATOR)
  276. /*
  277.  * Find exception in method.
  278.  */
  279. void
  280. findExceptionInMethod(uintp pc, classes* class, exceptionInfo* info)
  281. {
  282.     methods* ptr;
  283.  
  284.     for (ptr = methodList; ptr != 0; ptr = ptr->exception_next) {
  285.  
  286.         if (pc < (uintp)ptr->ncode || pc >= (uintp)ptr->ncode_end) {
  287.             continue;
  288.         }
  289. EDBG(        printf("Found method %s.%s%s\n", ptr->class->name,
  290.             ptr->pair->s1, ptr->pair->s2);            )
  291.  
  292.         if (findExceptionBlockInMethod(pc, class, ptr, info) == true) {
  293.             return;
  294.         }
  295.     }
  296. EDBG(    printf("Exception not found.\n");                )
  297.     info->handler = 0;
  298. }
  299.  
  300. /*
  301.  * Find method containing pc.
  302.  */
  303. methods*
  304. findMethodFromPC(uintp pc)
  305. {
  306.     methods* ptr;
  307.  
  308.     for (ptr = methodList; ptr != 0; ptr = ptr->exception_next) {
  309.         if (pc >= (uintp)ptr->ncode && pc < (uintp)ptr->ncode_end) {
  310. EDBG(            printf("Found method %s.%s%s\n",
  311.                 ptr->class->name,
  312.                 ptr->pair->s1, ptr->pair->s2);        )
  313.             break;
  314.         }
  315.     }
  316. EDBG(    if (ptr == 0) printf("Method not found.\n");            )
  317.  
  318.     return (ptr);
  319. }
  320. #endif
  321.  
  322. /*
  323.  * Look for exception block in method.
  324.  */
  325. bool
  326. findExceptionBlockInMethod(uintp pc, classes* class, methods* ptr, exceptionInfo* info)
  327. {
  328.     jexception* eptr;
  329.     classes* cptr;
  330.     int i;
  331.  
  332.     eptr = ptr->exception_table;
  333.  
  334. EDBG(    printf("Nr of exceptions = %d\n", ptr->exception_table_len); )
  335.  
  336.     /* Right method - look for exception */
  337.     for (i = 0; i < ptr->exception_table_len; i++) {
  338. EDBG(        printf("Exceptions %x (%x-%x)\n", pc, eptr[i].start_pc, eptr[i].end_pc); )
  339.         if (pc < eptr[i].start_pc || pc > eptr[i].end_pc) {
  340.             continue;
  341.         }
  342. EDBG(        printf("Found exception 0x%x\n", eptr[i].handler_pc); )
  343.  
  344.         /* Stash info for later date */
  345.         info->class = ptr->class;
  346.         info->handler = eptr[i].handler_pc;
  347.  
  348.         /* Found exception - is it right type */
  349.         if (eptr[i].catch_type == 0) {
  350.             return (true);
  351.         }
  352.         for (cptr = class; cptr != 0; cptr = cptr->superclass) {
  353.             if (cptr->name == eptr[i].catch_type) {
  354.                 return (true);
  355.             }
  356.         }
  357.     }
  358.     return (false);
  359. }
  360.