home *** CD-ROM | disk | FTP | other *** search
- /*
- * lookup.c
- * Various lookup calls for resolving objects, methods, exceptions, etc.
- *
- * Copyright (c) 1996 Systems Architecture Research Centre,
- * City University, London, UK.
- *
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- *
- * Written by Tim Wilkinson <tim@sarc.city.ac.uk>, February 1996.
- */
-
- #define DBG(s)
- #define FDBG(s)
- #define EDBG(s)
-
- #include <stdio.h>
- #include <assert.h>
- #include "gtypes.h"
- #include "errors.h"
- #include "constants.h"
- #include "classMethod.h"
- #include "lookup.h"
- #include "exception.h"
- #include "thread.h"
-
- extern strpair* initpair;
- extern methods* methodList;
- extern classes* ObjectClass;
-
- /*
- * Lookup a method reference and get the various interesting bits.
- */
- void
- getMethodSignatureClass(constIndex idx, constants* pool, callInfo* call)
- {
- constIndex ci;
- constIndex ni;
- constIndex nin;
- constIndex nis;
- char* str;
- int i;
- int inout[2];
- createInfo cls;
- strpair* pair;
-
- if (pool->tags[idx] != CONSTANT_Methodref &&
- pool->tags[idx] != CONSTANT_InterfaceMethodref) {
- DBG( printf("No Methodref found\n"); )
- throwException(NoSuchMethodError);
- }
-
- ni = METHODREF_NAMEANDTYPE(idx, pool);
- if (pool->tags[ni] != CONSTANT_NameAndType) {
- DBG( printf("No Methodref:NameAndType found\n"); )
- throwException(NoSuchMethodError);
- }
- nin = NAMEANDTYPE_NAME(ni, pool);
- if (pool->tags[nin] != CONSTANT_Utf8) {
- DBG( printf("No Methodref:NameAndType:Utf8 found\n"); )
- throwException(NoSuchMethodError);
- }
- nis = NAMEANDTYPE_SIGNATURE(ni, pool);
- if (pool->tags[nis] != CONSTANT_Utf8) {
- DBG( printf("No Methodref:NameAndType:Utf8 found\n"); )
- throwException(NoSuchMethodError);
- }
-
- ci = METHODREF_CLASS(idx, pool);
- if (pool->tags[ci] != CONSTANT_Class) {
- DBG( printf("No Methodref:Class found\n"); )
- throwException(NoSuchMethodError);
- }
- getClass(ci, pool, &cls);
-
- DBG( printf("lookupMethodSignatureClass(%s,%s,%s)\n",
- cls.class->name, pool->data[nin], pool->data[nis]); )
-
- /*
- * We now have a complete class and method signature. We can
- * Now work out some things we might need to know, like no. of
- * arguments, address of function, etc.
- */
- countInsAndOuts((char*)pool->data[nis], &call->in, &call->out);
- DBG( printf("in = %d, out = %d\n", call->in, call->out); )
- pair = lookupStringPair((char*)pool->data[nin], (char*)pool->data[nis]);
- assert(pair != 0);
- call->mtag = (int)pair;
- call->offset = pair->hash % MAXMETHOD;
- call->mtable = cls.class->mtable;
- }
-
- void
- getClass(constIndex idx, constants* pool, createInfo* create)
- {
- constIndex cs;
- classes* class;
- char* cname;
-
- if (pool->tags[idx] != CONSTANT_Class) {
- DBG( printf("No Class found\n"); )
- throwException(NoClassDefFoundError);
- }
-
- cs = CLASS_NAME(idx, pool);
- if (pool->tags[cs] != CONSTANT_Utf8) {
- DBG( printf("No Class:Utf8 found\n"); )
- throwException(NoClassDefFoundError);
- }
- cname = (char*)pool->data[cs];
-
- DBG( printf("Class name %s\n", cname); )
-
- /* If an array, then treat as an array */
- if (cname[0] == '[') {
- class = lookupArray(cname);
- }
- else {
- /* Lookup class */
- class = lookupClass(cname);
- }
- if (class == 0) {
- DBG( printf("Class %s not loaded.\n", cname); )
- throwException(NoClassDefFoundError);
- }
-
- create->class = class;
- }
-
- void
- getField(constIndex idx, bool isStatic, constants* pool, fieldInfo* fld)
- {
- constIndex cs;
- constIndex ci;
- constIndex ni;
- constIndex cis;
- constIndex nin;
- constIndex nis;
- fields* field;
-
- if (pool->tags[idx] != CONSTANT_Fieldref) {
- FDBG( printf("No Fieldref found\n"); )
- throwException(NoSuchFieldError);
- }
-
- ci = FIELDREF_CLASS(idx, pool);
- if (pool->tags[ci] != CONSTANT_Class) {
- FDBG( printf("No Methodref:Class found\n"); )
- throwException(NoSuchFieldError);
- }
- ni = FIELDREF_NAMEANDTYPE(idx, pool);
- if (pool->tags[ni] != CONSTANT_NameAndType) {
- FDBG( printf("No Methodref:NameAndType found\n"); )
- throwException(NoSuchFieldError);
- }
-
- cis = CLASS_NAME(ci, pool);
- if (pool->tags[cis] != CONSTANT_Utf8) {
- FDBG( printf("No Methodref:Class:Utf8 found\n"); )
- throwException(NoSuchFieldError);
- }
-
- nin = NAMEANDTYPE_NAME(ni, pool);
- if (pool->tags[nin] != CONSTANT_Utf8) {
- FDBG( printf("No Methodref:NameAndType:Utf8 found\n"); )
- throwException(NoSuchFieldError);
- }
- nis = NAMEANDTYPE_SIGNATURE(ni, pool);
- if (pool->tags[nis] != CONSTANT_Utf8) {
- FDBG( printf("No Methodref:NameAndType:Utf8 found\n"); )
- throwException(NoSuchFieldError);
- }
-
- FDBG( printf("*** getField(%s,%s,%s)\n",
- pool->data[cis], pool->data[nin], pool->data[nis]); )
-
- field = lookupClassField((char*)pool->data[cis], (char*)pool->data[nin], isStatic);
- if (field == 0) {
- FDBG( printf("Field not found\n"); )
- throwException(NoSuchFieldError);
- }
-
- fld->class = field->class;
- fld->size = field->size;
- fld->offset = field->offset;
-
- FDBG( printf("class=%s, classsize=%d, fldsize=%d, fldoffset=%d\n",
- fld->class->name, fld->class->fsize,
- fld->size, fld->offset); )
- }
-
- /*
- * Lookup a method (and translate) in the specified class.
- */
- void*
- findMethod(classes* class, strpair* pair)
- {
- methods* mptr;
- int r;
-
- classes* oclass;
- methods* omethod;
-
- oclass = class;
- omethod = 0;
-
- /*
- * Lookup method - this could be alot more efficient but never mind.
- * Also there is no attempt to honour PUBLIC, PRIVATE, etc.
- */
- for (; class != 0; class = class->superclass) {
- for (mptr = class->methodList; mptr != 0; mptr = mptr->next) {
- if (mptr->pair == pair) {
- /*
- * Generate code on demand.
- */
- if (mptr->ncode == 0) {
- intsDisable();
- translate(mptr);
- initClasses();
- intsRestore();
- }
- return (mptr->ncode);
- }
- omethod = mptr;
- }
- }
- return (0);
- }
-
- /*
- * Find exception in method.
- */
- void
- findExceptionInMethod(nativecode* pc, classes* class, exceptionInfo* info)
- {
- methods* ptr;
- exception* eptr;
- int i;
- classes* cptr;
-
- for (ptr = methodList; ptr != 0; ptr = ptr->exception_next) {
- if (pc < ptr->ncode || pc >= ptr->ncode_end) {
- continue;
- }
- EDBG( printf("Found method %s.%s%s\n", ptr->class->name,
- ptr->pair->s1, ptr->pair->s2); )
- eptr = ptr->exception_table;
-
- EDBG( printf("Nr of exceptions = %d\n", ptr->exception_table_len); )
-
- /* Right method - look for exception */
- for (i = 0; i < ptr->exception_table_len; i++) {
- EDBG( printf("Exceptions %x (%x-%x)\n", pc, eptr[i].start_pc, eptr[i].end_pc); )
- if (pc < (nativecode*)eptr[i].start_pc || pc > (nativecode*)eptr[i].end_pc) {
- continue;
- }
- EDBG( printf("Found exception 0x%x\n", eptr[i].handler_pc); )
-
- info->class = ptr->class;
- info->handler = eptr[i].handler_pc;
-
- /* Found exception - is it right type */
- if (eptr[i].catch_type == 0) {
- return;
- }
- for (cptr = class; cptr != 0; cptr = cptr->superclass) {
- if (cptr->name == eptr[i].catch_type) {
- return;
- }
- }
- }
- break;
- }
- EDBG( printf("Exception not found.\n"); )
- info->handler = 0;
- }
-