extern "C" void* j3ResolveStaticStub() {
  JavaThread *th = JavaThread::get();
  void* result = NULL;

  // Lookup the caller of this class.
  vmkit::StackWalker Walker(th);
  ++Walker; // Remove the stub.
  vmkit::FrameInfo* FI = Walker.get();
  assert(FI->Metadata != NULL && "Wrong stack trace");
  JavaMethod* caller = (JavaMethod*)FI->Metadata;

  // Lookup the method info in the constant pool of the caller.
  uint16 ctpIndex = caller->lookupCtpIndex(FI);
  assert(ctpIndex && "No constant pool index");
  JavaConstantPool* ctpInfo = caller->classDef->getConstantPool();
  CommonClass* cl = 0;
  const UTF8* utf8 = 0;
  Signdef* sign = 0;

  ctpInfo->resolveMethod(ctpIndex, cl, utf8, sign);
  UserClass* lookup = cl->isArray() ? cl->super : cl->asClass();
  assert(lookup->isInitializing() && "Class not ready");
  JavaMethod* callee = lookup->lookupMethod(utf8, sign->keyName, true, true, 0);

  // Compile the found method.
  result = callee->compiledPtr();
    
  // Update the entry in the constant pool.
  ctpInfo->ctpRes[ctpIndex] = result;

  return result;
}
JavaClass::JavaClass(jobject anInstance)
{
    jobject aClass = callJNIMethod<jobject>(anInstance, "getClass", "()Ljava/lang/Class;");

    if (!aClass) {
        LOG_ERROR("Unable to call getClass on instance %p", anInstance);
        m_name = fastStrDup("<Unknown>");
        return;
    }

    if (jstring className = (jstring)callJNIMethod<jobject>(aClass, "getName", "()Ljava/lang/String;")) {
        const char* classNameC = getCharactersFromJString(className);
        m_name = fastStrDup(classNameC);
        releaseCharactersForJString(className, classNameC);
    } else
        m_name = fastStrDup("<Unknown>");

    int i;
    JNIEnv* env = getJNIEnv();

    // Get the fields
    if (jarray fields = (jarray)callJNIMethod<jobject>(aClass, "getFields", "()[Ljava/lang/reflect/Field;")) {
        int numFields = env->GetArrayLength(fields);
        for (i = 0; i < numFields; i++) {
            jobject aJField = env->GetObjectArrayElement((jobjectArray)fields, i);
            JavaField* aField = new JavaField(env, aJField); // deleted in the JavaClass destructor
            {
                JSLock lock(SilenceAssertionsOnly);
                m_fields.set(((UString)aField->name()).rep(), aField);
            }
            env->DeleteLocalRef(aJField);
        }
        env->DeleteLocalRef(fields);
    }

    // Get the methods
    if (jarray methods = (jarray)callJNIMethod<jobject>(aClass, "getMethods", "()[Ljava/lang/reflect/Method;")) {
        int numMethods = env->GetArrayLength(methods);
        for (i = 0; i < numMethods; i++) {
            jobject aJMethod = env->GetObjectArrayElement((jobjectArray)methods, i);
            JavaMethod* aMethod = new JavaMethod(env, aJMethod); // deleted in the JavaClass destructor
            MethodList* methodList;
            {
                JSLock lock(SilenceAssertionsOnly);

                methodList = m_methods.get(((UString)aMethod->name()).rep());
                if (!methodList) {
                    methodList = new MethodList();
                    m_methods.set(((UString)aMethod->name()).rep(), methodList);
                }
            }
            methodList->append(aMethod);
            env->DeleteLocalRef(aJMethod);
        }
        env->DeleteLocalRef(methods);
    }

    env->DeleteLocalRef(aClass);
}
Exemple #3
0
bool enqueueReference(gc* _obj) {
  Jnjvm* vm = JavaThread::get()->getJVM();
  JavaObject* obj = (JavaObject*)_obj;
  llvm_gcroot(obj, 0);
  JavaMethod* meth = vm->upcalls->EnqueueReference;
  UserClass* cl = JavaObject::getClass(obj)->asClass();
  return (bool)meth->invokeIntSpecialBuf(vm, cl, obj, 0);
}
Exemple #4
0
void invokeFinalizer(gc* _obj) {
  Jnjvm* vm = JavaThread::get()->getJVM();
  JavaObject* obj = (JavaObject*)_obj;
  llvm_gcroot(obj, 0);
  JavaMethod* meth = vm->upcalls->FinalizeObject;
  UserClass* cl = JavaObject::getClass(obj)->asClass();
  meth->invokeIntVirtualBuf(vm, cl, obj, 0);
}
JavaClassJobject::JavaClassJobject(jobject anInstance, bool requireAnnotation)
    : m_requireAnnotation(requireAnnotation)
#else
JavaClassJobject::JavaClassJobject(jobject anInstance)
#endif
{
    jobject aClass = callJNIMethod<jobject>(anInstance, "getClass", "()Ljava/lang/Class;");

    if (!aClass) {
        LOG_ERROR("unable to call getClass on instance %p", anInstance);
        return;
    }

    JNIEnv* env = getJNIEnv();

    // Get the fields
    jarray fields = static_cast<jarray>(callJNIMethod<jobject>(aClass, "getFields", "()[Ljava/lang/reflect/Field;"));
    int numFields = env->GetArrayLength(fields);
    for (int i = 0; i < numFields; i++) {
        jobject aJField = env->GetObjectArrayElement(static_cast<jobjectArray>(fields), i);
        JavaField* aField = new JavaFieldJobject(env, aJField); // deleted in the JavaClass destructor
        m_fields.set(aField->name(), aField);
        env->DeleteLocalRef(aJField);
    }

    // Get the methods
    jarray methods = static_cast<jarray>(callJNIMethod<jobject>(aClass, "getMethods", "()[Ljava/lang/reflect/Method;"));
    int numMethods = env->GetArrayLength(methods);
#if PLATFORM(ANDROID)
    jmethodID isAnnotationPresentMethodID = getAnnotationMethodID(env);
    if (!isAnnotationPresentMethodID) {
        LOG_ERROR("unable to find method %s on instance %p", kIsAnnotationPresent, anInstance);
        return;
    }
#endif
    for (int i = 0; i < numMethods; i++) {
        jobject aJMethod = env->GetObjectArrayElement(static_cast<jobjectArray>(methods), i);
#if PLATFORM(ANDROID)
        if (jsAccessAllowed(env, isAnnotationPresentMethodID, aJMethod)) {
#endif
            JavaMethod* aMethod = new JavaMethodJobject(env, aJMethod); // deleted in the JavaClass destructor
            MethodList* methodList = m_methods.get(aMethod->name());
            if (!methodList) {
                methodList = new MethodList();
                m_methods.set(aMethod->name(), methodList);
            }
            methodList->append(aMethod);
#if PLATFORM(ANDROID)
        }
#endif
        env->DeleteLocalRef(aJMethod);
    }
    env->DeleteLocalRef(fields);
    env->DeleteLocalRef(methods);
    env->DeleteLocalRef(aClass);
}
Exemple #6
0
JavaClass::JavaClass(jobject anInstance)
{
    jobject aClass = callJNIMethod<jobject>(anInstance, "getClass", "()Ljava/lang/Class;");

    if (!aClass) {
        fprintf(stderr, "%s:  unable to call getClass on instance %p\n", __PRETTY_FUNCTION__, anInstance);
        return;
    }

    jstring className = (jstring)callJNIMethod<jobject>(aClass, "getName", "()Ljava/lang/String;");
    const char *classNameC = getCharactersFromJString(className);
    _name = strdup(classNameC);
    releaseCharactersForJString(className, classNameC);

    int i;
    JNIEnv *env = getJNIEnv();

    // Get the fields
    jarray fields = (jarray)callJNIMethod<jobject>(aClass, "getFields", "()[Ljava/lang/reflect/Field;");
    int numFields = env->GetArrayLength(fields);
    for (i = 0; i < numFields; i++) {
        jobject aJField = env->GetObjectArrayElement((jobjectArray)fields, i);
        JavaField *aField = new JavaField(env, aJField); // deleted in the JavaClass destructor
        {
            JSLock lock(SilenceAssertionsOnly);
            _fields.set(aField->name(), aField);
        }
        env->DeleteLocalRef(aJField);
    }

    // Get the methods
    jarray methods = (jarray)callJNIMethod<jobject>(aClass, "getMethods", "()[Ljava/lang/reflect/Method;");
    int numMethods = env->GetArrayLength(methods);
    for (i = 0; i < numMethods; i++) {
        jobject aJMethod = env->GetObjectArrayElement((jobjectArray)methods, i);
        JavaMethod *aMethod = new JavaMethod(env, aJMethod); // deleted in the JavaClass destructor
        MethodList* methodList;
        {
            JSLock lock(SilenceAssertionsOnly);

            methodList = _methods.get(aMethod->name());
            if (!methodList) {
                methodList = new MethodList();
                _methods.set(aMethod->name(), methodList);
            }
        }
        methodList->append(aMethod);
        env->DeleteLocalRef(aJMethod);
    }
}
Exemple #7
0
bool JavaNPObjectInvoke(NPObject* obj, NPIdentifier identifier, const NPVariant* args, uint32_t argCount, NPVariant* result)
{
    JavaInstance* instance = ExtractJavaInstance(obj);
    if (!instance)
        return false;
    NPUTF8* name = _NPN_UTF8FromIdentifier(identifier);
    if (!name)
        return false;
		
    instance->begin();

    MethodList methodList = instance->getClass()->methodsNamed(name);
    // TODO: use NPN_MemFree
    free(name);

    // Try to find a good match for the overloaded method. The
    // fundamental problem is that JavaScript doesn't have the
    // notion of method overloading and Java does. We could
    // get a bit more sophisticated and attempt to do some
    // type checking as well as checking the number of parameters.
    size_t numMethods = methodList.size();
    JavaMethod* aMethod;
    JavaMethod* jMethod = 0;
    for (size_t methodIndex = 0; methodIndex < numMethods; methodIndex++) {
        aMethod = methodList[methodIndex];
        if (aMethod->numParameters() == static_cast<int>(argCount)) {
            jMethod = aMethod;
            break;
        }
    }
    if (!jMethod) {
        instance->end();
        return false;
    }

    JavaValue* jArgs = new JavaValue[argCount];
    for (unsigned int i = 0; i < argCount; i++)
        jArgs[i] = convertNPVariantToJavaValue(args[i], jMethod->parameterAt(i));

    JavaValue jResult = instance->invokeMethod(jMethod, jArgs);
    instance->end();
    delete[] jArgs;

    VOID_TO_NPVARIANT(*result);
    convertJavaValueToNPVariant(jResult, result);
    return true;
}
Exemple #8
0
void Classpath::initialiseClasspath(JnjvmClassLoader* loader) {

  newClassLoader = 
    UPCALL_CLASS(loader, "java/lang/ClassLoader");
  
  getSystemClassLoader =
    UPCALL_METHOD(loader, "java/lang/ClassLoader", "getSystemClassLoader",
                  "()Ljava/lang/ClassLoader;", ACC_STATIC);

  setContextClassLoader =
    UPCALL_METHOD(loader, "java/lang/Thread", "setContextClassLoader",
                  "(Ljava/lang/ClassLoader;)V", ACC_VIRTUAL);

  newString = 
    UPCALL_CLASS(loader, "java/lang/String");
  
  newClass =
    UPCALL_CLASS(loader, "java/lang/Class");
  
  newThrowable =
    UPCALL_CLASS(loader, "java/lang/Throwable");
  
  newException =
    UPCALL_CLASS(loader, "java/lang/Exception");

  newPointer32 = 
    UPCALL_CLASS(loader, "gnu/classpath/Pointer32");
  
  newPointer64 = 
    UPCALL_CLASS(loader, "gnu/classpath/Pointer64");
 
  newDirectByteBuffer =
    UPCALL_CLASS(loader, "java/nio/DirectByteBufferImpl$ReadWrite");

  InitDirectByteBuffer =
    UPCALL_METHOD(loader, "java/nio/DirectByteBufferImpl$ReadWrite", "<init>",
                  "(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V",
                  ACC_VIRTUAL);

  initClass =
    UPCALL_METHOD(loader, "java/lang/Class", "<init>", "(Ljava/lang/Object;)V",
                  ACC_VIRTUAL);

  initClassWithProtectionDomain =
    UPCALL_METHOD(loader, "java/lang/Class", "<init>",
                  "(Ljava/lang/Object;Ljava/security/ProtectionDomain;)V",
                  ACC_VIRTUAL);

  vmdataClass =
    UPCALL_FIELD(loader, "java/lang/Class", "vmdata", "Ljava/lang/Object;",
                 ACC_VIRTUAL);
  
  setProperty = 
    UPCALL_METHOD(loader, "java/util/Properties", "setProperty",
                  "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;",
                  ACC_VIRTUAL);

  initString =
    UPCALL_METHOD(loader, "java/lang/String", "<init>", "([CIIZ)V", ACC_VIRTUAL);
  
  initConstructor =
      UPCALL_METHOD(loader, "java/lang/reflect/Constructor", "<init>",
                    "(Ljava/lang/reflect/VMConstructor;)V", ACC_VIRTUAL);

  initVMConstructor =
    UPCALL_METHOD(loader, "java/lang/reflect/VMConstructor", "<init>",
                  "(Ljava/lang/Class;I)V", ACC_VIRTUAL);

  newConstructor =
    UPCALL_CLASS(loader, "java/lang/reflect/Constructor");

  newVMConstructor =
		  UPCALL_CLASS(loader, "java/lang/reflect/VMConstructor");

  constructorArrayClass =
    UPCALL_ARRAY_CLASS(loader, "java/lang/reflect/Constructor", 1);
  
  constructorArrayAnnotation =
    UPCALL_ARRAY_CLASS(loader, "java/lang/annotation/Annotation", 1);

  constructorSlot =
    UPCALL_FIELD(loader, "java/lang/reflect/Constructor", "slot", "I", ACC_VIRTUAL);
    
    
  newHashMap =
    UPCALL_CLASS(loader, "java/util/HashMap");

  initHashMap =
    UPCALL_METHOD(loader, "java/util/HashMap", "<init>",
                  "()V", ACC_VIRTUAL);  
  putHashMap =
    UPCALL_METHOD(loader, "java/util/HashMap", "put",
                  "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
		  ACC_VIRTUAL);

  newAnnotationHandler = 
    UPCALL_CLASS(loader, "sun/reflect/annotation/AnnotationInvocationHandler");

  createAnnotation =
    UPCALL_METHOD(loader, "sun/reflect/annotation/AnnotationInvocationHandler",
		  "create", "(Ljava/lang/Class;Ljava/util/Map;)Ljava/lang/annotation/Annotation;",
		  ACC_STATIC);

  annotationArrayClass =
    UPCALL_ARRAY_CLASS(loader, "java/lang/annotation/Annotation", 1);
    
  newAnnotation =
    UPCALL_CLASS(loader, "java/lang/annotation/Annotation");

  
  initMethod =
    UPCALL_METHOD(loader, "java/lang/reflect/Method", "<init>",
                  "(Ljava/lang/reflect/VMMethod;)V", ACC_VIRTUAL);

  initVMMethod =
      UPCALL_METHOD(loader, "java/lang/reflect/VMMethod", "<init>",
                    "()V", ACC_VIRTUAL);

   // Ljava/lang/Class;Ljava/lang/String;I
  newMethod =
    UPCALL_CLASS(loader, "java/lang/reflect/Method");

  newVMMethod =
      UPCALL_CLASS(loader, "java/lang/reflect/VMMethod");

  methodArrayClass =
    UPCALL_ARRAY_CLASS(loader, "java/lang/reflect/Method", 1);

  methodSlot =
    UPCALL_FIELD(loader, "java/lang/reflect/Method", "slot", "I", ACC_VIRTUAL);
  
  initField =
    UPCALL_METHOD(loader, "java/lang/reflect/Field", "<init>",
                  "(Ljava/lang/reflect/VMField;)V", ACC_VIRTUAL);

  initVMField =
      UPCALL_METHOD(loader, "java/lang/reflect/VMField", "<init>",
                    "(Ljava/lang/Class;Ljava/lang/String;I)V", ACC_VIRTUAL);

  getFieldInClass = UPCALL_METHOD(loader, "java/lang/Class", "getField",
            "(Ljava/lang/String;)Ljava/lang/reflect/Field;", ACC_VIRTUAL);

  getInField = UPCALL_METHOD(loader, "java/lang/reflect/Field", "get",
          "(Ljava/lang/Object;)Ljava/lang/Object;", ACC_VIRTUAL);

  newField =
    UPCALL_CLASS(loader, "java/lang/reflect/Field");

  newVMField =
      UPCALL_CLASS(loader, "java/lang/reflect/VMField");

  fieldArrayClass =
    UPCALL_ARRAY_CLASS(loader, "java/lang/reflect/Field", 1);
  
  fieldSlot =
    UPCALL_FIELD(loader, "java/lang/reflect/Field", "slot", "I", ACC_VIRTUAL);
  
  
  classArrayClass =
    UPCALL_ARRAY_CLASS(loader, "java/lang/Class", 1);
  
  newVMThrowable =
    UPCALL_CLASS(loader, "java/lang/VMThrowable");
  
  initVMThrowable =
    UPCALL_METHOD(loader, "java/lang/VMThrowable", "<init>", "()V", ACC_VIRTUAL);

  vmDataVMThrowable =
    UPCALL_FIELD(loader, "java/lang/VMThrowable", "vmdata", "Ljava/lang/Object;",
                 ACC_VIRTUAL);

  bufferAddress =
    UPCALL_FIELD(loader, "java/nio/Buffer", "address", "Lgnu/classpath/Pointer;",
                 ACC_VIRTUAL);

  dataPointer32 =
    UPCALL_FIELD(loader, "gnu/classpath/Pointer32", "data", "I", ACC_VIRTUAL);
  
  dataPointer64 =
    UPCALL_FIELD(loader, "gnu/classpath/Pointer64", "data", "J", ACC_VIRTUAL);

  vmdataClassLoader =
    UPCALL_FIELD(loader, "java/lang/ClassLoader", "vmdata", "Ljava/lang/Object;",
                 ACC_VIRTUAL);
  
  newStackTraceElement =
    UPCALL_CLASS(loader, "java/lang/StackTraceElement");
  
  stackTraceArray =
    UPCALL_ARRAY_CLASS(loader, "java/lang/StackTraceElement", 1);

  initStackTraceElement =
    UPCALL_METHOD(loader,  "java/lang/StackTraceElement", "<init>",
                  "(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Z)V",
                  ACC_VIRTUAL);

  boolValue =
    UPCALL_FIELD(loader, "java/lang/Boolean", "value", "Z", ACC_VIRTUAL);
  
  byteValue =
    UPCALL_FIELD(loader, "java/lang/Byte", "value", "B", ACC_VIRTUAL);

  shortValue =
    UPCALL_FIELD(loader, "java/lang/Short", "value", "S", ACC_VIRTUAL);

  charValue =
    UPCALL_FIELD(loader, "java/lang/Character", "value", "C", ACC_VIRTUAL);

  intValue =
    UPCALL_FIELD(loader, "java/lang/Integer", "value", "I", ACC_VIRTUAL);

  longValue =
    UPCALL_FIELD(loader, "java/lang/Long", "value", "J", ACC_VIRTUAL);

  floatValue =
    UPCALL_FIELD(loader, "java/lang/Float", "value", "F", ACC_VIRTUAL);

  doubleValue =
    UPCALL_FIELD(loader, "java/lang/Double", "value", "D", ACC_VIRTUAL);

  Classpath::voidClass =
    UPCALL_CLASS(loader, "java/lang/Void");
  
  Classpath::boolClass =
    UPCALL_CLASS(loader, "java/lang/Boolean");

  Classpath::byteClass =
    UPCALL_CLASS(loader, "java/lang/Byte");

  Classpath::shortClass =
    UPCALL_CLASS(loader, "java/lang/Short");

  Classpath::charClass =
    UPCALL_CLASS(loader, "java/lang/Character"); 

  Classpath::intClass =
    UPCALL_CLASS(loader, "java/lang/Integer");

  Classpath::floatClass =
    UPCALL_CLASS(loader, "java/lang/Float");

  Classpath::doubleClass =
    UPCALL_CLASS(loader, "java/lang/Double");

  Classpath::longClass =
    UPCALL_CLASS(loader, "java/lang/Long");
  
  Classpath::OfObject =
    UPCALL_CLASS(loader, "java/lang/Object");

  vmStackWalker =
    UPCALL_CLASS(loader, "gnu/classpath/VMStackWalker");

  loadInClassLoader =
    UPCALL_METHOD(loader, "java/lang/ClassLoader", "loadClass",
                  "(Ljava/lang/String;)Ljava/lang/Class;", ACC_VIRTUAL);

  internString =
    UPCALL_METHOD(loader, "java/lang/VMString", "intern",
                  "(Ljava/lang/String;)Ljava/lang/String;", ACC_STATIC); 
  
  JavaMethod* isArray =
    UPCALL_METHOD(loader, "java/lang/Class", "isArray", "()Z", ACC_VIRTUAL);
  isArray->setNative();

  // Make sure classes the JIT optimizes on are loaded.
  UPCALL_CLASS(loader, "java/lang/VMFloat");
  UPCALL_CLASS(loader, "java/lang/VMDouble");

  UPCALL_REFLECT_CLASS_EXCEPTION(loader, InvocationTargetException);
  UPCALL_CLASS_EXCEPTION(loader, ArrayStoreException);
  UPCALL_CLASS_EXCEPTION(loader, ClassCastException);
  UPCALL_CLASS_EXCEPTION(loader, IllegalMonitorStateException);
  UPCALL_CLASS_EXCEPTION(loader, IllegalArgumentException);
  UPCALL_CLASS_EXCEPTION(loader, InterruptedException);
  UPCALL_CLASS_EXCEPTION(loader, IndexOutOfBoundsException);
  UPCALL_CLASS_EXCEPTION(loader, ArrayIndexOutOfBoundsException);
  UPCALL_CLASS_EXCEPTION(loader, NegativeArraySizeException);
  UPCALL_CLASS_EXCEPTION(loader, NullPointerException);
  UPCALL_CLASS_EXCEPTION(loader, SecurityException);
  UPCALL_CLASS_EXCEPTION(loader, ClassFormatError);
  UPCALL_CLASS_EXCEPTION(loader, ClassCircularityError);
  UPCALL_CLASS_EXCEPTION(loader, NoClassDefFoundError);
  UPCALL_CLASS_EXCEPTION(loader, UnsupportedClassVersionError);
  UPCALL_CLASS_EXCEPTION(loader, NoSuchFieldError);
  UPCALL_CLASS_EXCEPTION(loader, NoSuchMethodError);
  UPCALL_CLASS_EXCEPTION(loader, InstantiationError);
  UPCALL_CLASS_EXCEPTION(loader, InstantiationException);
  UPCALL_CLASS_EXCEPTION(loader, IllegalAccessError);
  UPCALL_CLASS_EXCEPTION(loader, IllegalAccessException);
  UPCALL_CLASS_EXCEPTION(loader, VerifyError);
  UPCALL_CLASS_EXCEPTION(loader, ExceptionInInitializerError);
  UPCALL_CLASS_EXCEPTION(loader, LinkageError);
  UPCALL_CLASS_EXCEPTION(loader, AbstractMethodError);
  UPCALL_CLASS_EXCEPTION(loader, UnsatisfiedLinkError);
  UPCALL_CLASS_EXCEPTION(loader, InternalError);
  UPCALL_CLASS_EXCEPTION(loader, OutOfMemoryError);
  UPCALL_CLASS_EXCEPTION(loader, StackOverflowError);
  UPCALL_CLASS_EXCEPTION(loader, UnknownError);
  UPCALL_CLASS_EXCEPTION(loader, ClassNotFoundException);
  UPCALL_CLASS_EXCEPTION(loader, ArithmeticException);
  UPCALL_CLASS_EXCEPTION(loader, CloneNotSupportedException);
  
  UPCALL_METHOD_EXCEPTION(loader, InvocationTargetException);
  UPCALL_METHOD_EXCEPTION(loader, ArrayStoreException);
  UPCALL_METHOD_EXCEPTION(loader, ClassCastException);
  UPCALL_METHOD_EXCEPTION(loader, IllegalMonitorStateException);
  UPCALL_METHOD_EXCEPTION(loader, IllegalArgumentException);
  UPCALL_METHOD_EXCEPTION(loader, InterruptedException);
  UPCALL_METHOD_EXCEPTION(loader, IndexOutOfBoundsException);
  UPCALL_METHOD_EXCEPTION(loader, ArrayIndexOutOfBoundsException);
  UPCALL_METHOD_EXCEPTION(loader, NegativeArraySizeException);
  UPCALL_METHOD_EXCEPTION(loader, NullPointerException);
  UPCALL_METHOD_EXCEPTION(loader, SecurityException);
  UPCALL_METHOD_EXCEPTION(loader, ClassFormatError);
  UPCALL_METHOD_EXCEPTION(loader, ClassCircularityError);
  UPCALL_METHOD_EXCEPTION(loader, NoClassDefFoundError);
  UPCALL_METHOD_EXCEPTION(loader, UnsupportedClassVersionError);
  UPCALL_METHOD_EXCEPTION(loader, NoSuchFieldError);
  UPCALL_METHOD_EXCEPTION(loader, NoSuchMethodError);
  UPCALL_METHOD_EXCEPTION(loader, InstantiationError);
  UPCALL_METHOD_EXCEPTION(loader, InstantiationException);
  UPCALL_METHOD_EXCEPTION(loader, IllegalAccessError);
  UPCALL_METHOD_EXCEPTION(loader, IllegalAccessException);
  UPCALL_METHOD_EXCEPTION(loader, VerifyError);
  UPCALL_METHOD_EXCEPTION(loader, ExceptionInInitializerError);
  UPCALL_METHOD_EXCEPTION(loader, LinkageError);
  UPCALL_METHOD_EXCEPTION(loader, AbstractMethodError);
  UPCALL_METHOD_EXCEPTION(loader, UnsatisfiedLinkError);
  UPCALL_METHOD_EXCEPTION(loader, InternalError);
  UPCALL_METHOD_EXCEPTION(loader, OutOfMemoryError);
  UPCALL_METHOD_EXCEPTION(loader, StackOverflowError);
  UPCALL_METHOD_EXCEPTION(loader, UnknownError);
  UPCALL_METHOD_EXCEPTION(loader, ClassNotFoundException);
  UPCALL_METHOD_EXCEPTION(loader, ArithmeticException);
  UPCALL_METHOD_EXCEPTION(loader, CloneNotSupportedException);
  
  UPCALL_METHOD_WITH_EXCEPTION(loader, NoClassDefFoundError);
  UPCALL_METHOD_WITH_EXCEPTION(loader, ExceptionInInitializerError);
  UPCALL_METHOD_WITH_EXCEPTION(loader, InvocationTargetException);

  InitObject = UPCALL_METHOD(loader, "java/lang/Object", "<init>", "()V",
                             ACC_VIRTUAL);
  
  FinalizeObject = UPCALL_METHOD(loader, "java/lang/Object", "finalize", "()V",
                                 ACC_VIRTUAL);
  
  IntToString = UPCALL_METHOD(loader, "java/lang/Integer", "toString",
                              "(II)Ljava/lang/String;", ACC_STATIC);

  SystemArraycopy = UPCALL_METHOD(loader, "java/lang/System", "arraycopy",
                                  "(Ljava/lang/Object;ILjava/lang/Object;II)V",
                                  ACC_STATIC);
  
  SystemExit = UPCALL_METHOD(loader, "java/lang/System", "exit",
          "(I)V", ACC_STATIC);

  VMSystemArraycopy = UPCALL_METHOD(loader, "java/lang/VMSystem", "arraycopy",
                                  "(Ljava/lang/Object;ILjava/lang/Object;II)V",
                                  ACC_STATIC);
  
  SystemClass = UPCALL_CLASS(loader, "java/lang/System");
  EnumClass = UPCALL_CLASS(loader, "java/lang/Enum");

  cloneableClass = UPCALL_CLASS(loader, "java/lang/Cloneable");

  newThread = 
    UPCALL_CLASS(loader, "java/lang/Thread");
  
  newVMThread = 
    UPCALL_CLASS(loader, "java/lang/VMThread");
  
  assocThread = 
    UPCALL_FIELD(loader, "java/lang/VMThread", "thread", "Ljava/lang/Thread;",
                 ACC_VIRTUAL);
  
  vmdataVMThread = 
    UPCALL_FIELD(loader, "java/lang/VMThread", "vmdata", "Ljava/lang/Object;",
                 ACC_VIRTUAL);
  
  inheritableThreadLocal = 
    UPCALL_CLASS(loader, "java/lang/InheritableThreadLocal");

  finaliseCreateInitialThread = 
    UPCALL_METHOD(loader, "java/lang/InheritableThreadLocal", "newChildThread",
                  "(Ljava/lang/Thread;)V", ACC_STATIC);
  
  initThread = 
    UPCALL_METHOD(loader, "java/lang/Thread", "<init>",
                  "(Ljava/lang/VMThread;Ljava/lang/String;IZ)V", ACC_VIRTUAL);
  
  initVMThread = 
    UPCALL_METHOD(loader, "java/lang/VMThread", "<init>",
                  "(Ljava/lang/Thread;)V", ACC_VIRTUAL);
  
  runVMThread = 
    UPCALL_METHOD(loader, "java/lang/VMThread", "run", "()V", ACC_VIRTUAL);


  groupAddThread = 
    UPCALL_METHOD(loader, "java/lang/ThreadGroup", "addThread",
                  "(Ljava/lang/Thread;)V", ACC_VIRTUAL);
  
  initGroup = 
    UPCALL_METHOD(loader, "java/lang/ThreadGroup", "<init>",
                  "()V", ACC_VIRTUAL);
  
  groupName = 
    UPCALL_FIELD(loader, "java/lang/ThreadGroup", "name", "Ljava/lang/String;",
                 ACC_VIRTUAL);
  
  threadName = 
     UPCALL_FIELD(loader, "java/lang/Thread", "name", "Ljava/lang/String;",
                  ACC_VIRTUAL);
   

  priority = 
    UPCALL_FIELD(loader,  "java/lang/Thread", "priority", "I", ACC_VIRTUAL);

  daemon = 
    UPCALL_FIELD(loader, "java/lang/Thread", "daemon", "Z", ACC_VIRTUAL);

  group =
    UPCALL_FIELD(loader, "java/lang/Thread", "group",
                 "Ljava/lang/ThreadGroup;", ACC_VIRTUAL);
  
  running = 
    UPCALL_FIELD(loader, "java/lang/VMThread", "running", "Z", ACC_VIRTUAL);
  
  threadGroup = 
    UPCALL_CLASS(loader, "java/lang/ThreadGroup");
  
  rootGroup =
    UPCALL_FIELD(loader, "java/lang/ThreadGroup", "root",
                 "Ljava/lang/ThreadGroup;", ACC_STATIC);

  vmThread = 
    UPCALL_FIELD(loader, "java/lang/Thread", "vmThread",
                 "Ljava/lang/VMThread;", ACC_VIRTUAL);
  
  getUncaughtExceptionHandler = 
    UPCALL_METHOD(loader, "java/lang/Thread", "getUncaughtExceptionHandler",
                  "()Ljava/lang/Thread$UncaughtExceptionHandler;", ACC_VIRTUAL);
  
  uncaughtException = 
    UPCALL_METHOD(loader, "java/lang/Thread$UncaughtExceptionHandler",
                  "uncaughtException",
                  "(Ljava/lang/Thread;Ljava/lang/Throwable;)V", ACC_VIRTUAL);

  
  methodClass =
    UPCALL_FIELD(loader, "java/lang/reflect/Method", "declaringClass",
                 "Ljava/lang/Class;", ACC_VIRTUAL);
  
  fieldClass =
    UPCALL_FIELD(loader, "java/lang/reflect/Field", "declaringClass",
                 "Ljava/lang/Class;", ACC_VIRTUAL);
  
  constructorClass =
    UPCALL_FIELD(loader, "java/lang/reflect/Constructor", "clazz",
                 "Ljava/lang/Class;", ACC_VIRTUAL);

  loader->loadName(loader->asciizConstructUTF8("java/lang/String"), 
                                       true, false, NULL);

  loader->loadName(loader->asciizConstructUTF8("java/lang/Object"), 
                                       true, false, NULL);
  
  // Don't compile methods here, we still don't know where to allocate Java
  // strings.
  
  JavaMethod* getEnv =
    UPCALL_METHOD(loader, "java/lang/VMSystem", "getenv",
                  "(Ljava/lang/String;)Ljava/lang/String;", ACC_STATIC);
  getEnv->setNative();

  JavaMethod* getCallingClass =
    UPCALL_METHOD(loader, "gnu/classpath/VMStackWalker", "getCallingClass",
                  "()Ljava/lang/Class;", ACC_STATIC);
  getCallingClass->setNative();
  
  JavaMethod* getCallingClassLoader =
    UPCALL_METHOD(loader, "gnu/classpath/VMStackWalker", "getCallingClassLoader",
                  "()Ljava/lang/ClassLoader;", ACC_STATIC);
  getCallingClassLoader->setNative();
  
  JavaMethod* firstNonNullClassLoader =
    UPCALL_METHOD(loader, "gnu/classpath/VMStackWalker", "firstNonNullClassLoader",
                  "()Ljava/lang/ClassLoader;", ACC_STATIC);
  firstNonNullClassLoader->setNative();
  
  JavaMethod* getCallerClass =
    UPCALL_METHOD(loader, "sun/reflect/Reflection", "getCallerClass",
                  "(I)Ljava/lang/Class;", ACC_STATIC);
  getCallerClass->setNative();
  
  JavaMethod* postProperties =
    UPCALL_METHOD(loader, "gnu/classpath/VMSystemProperties", "postInit",
                  "(Ljava/util/Properties;)V", ACC_STATIC);
  postProperties->setNative();

  // Also implement these twos, implementation in GNU Classpath 0.97.2 is buggy.
  JavaMethod* getAnnotation =
    UPCALL_METHOD(loader, "java/lang/reflect/AccessibleObject", "getAnnotation",
                  "(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;",
                  ACC_VIRTUAL);
  getAnnotation->setNative();
  
  JavaMethod* getAnnotations =
    UPCALL_METHOD(loader, "java/lang/reflect/AccessibleObject",
                  "getDeclaredAnnotations",
                  "()[Ljava/lang/annotation/Annotation;",
                  ACC_VIRTUAL);
  getAnnotations->setNative();
  
  JavaMethod* getBootPackages =
    UPCALL_METHOD(loader, "java/lang/VMClassLoader", "getBootPackages",
                  "()[Ljava/lang/String;", ACC_STATIC);
  getBootPackages->setNative();
  
  //===----------------------------------------------------------------------===//
  //
  // To make classes non GC-allocated, we have to bypass the tracer functions of
  // java.lang.Class, java.lang.reflect.Field, java.lang.reflect.Method and
  // java.lang.reflect.constructor. The new tracer functions trace the classloader
  // instead of the class/field/method.
  //
  //===----------------------------------------------------------------------===//
 
  newClass->getVirtualVT()->setNativeTracer(
      (word_t)nativeJavaObjectClassTracer,
       "nativeJavaObjectClassTracer");

  newConstructor->getVirtualVT()->setNativeTracer(
      (word_t)nativeJavaObjectConstructorTracer,
      "nativeJavaObjectConstructorTracer");

   newMethod->getVirtualVT()->setNativeTracer(
      (word_t)nativeJavaObjectMethodTracer,
      "nativeJavaObjectMethodTracer");

   newField->getVirtualVT()->setNativeTracer(
      (word_t)nativeJavaObjectFieldTracer,
      "nativeJavaObjectFieldTracer"); 
   
   newVMThread->getVirtualVT()->setNativeTracer(
      (word_t)nativeJavaObjectVMThreadTracer,
      "nativeJavaObjectVMThreadTracer");
 
  newReference = UPCALL_CLASS(loader, "java/lang/ref/Reference");
    
  EnqueueReference = 
    UPCALL_METHOD(loader, "java/lang/ref/Reference",  "enqueue", "()Z",
                  ACC_VIRTUAL);
 
  JavaMethod* initWeakReference =
    UPCALL_METHOD(loader, "java/lang/ref/WeakReference", "<init>",
                  "(Ljava/lang/Object;)V",
                  ACC_VIRTUAL);
  initWeakReference->setNative();
  
  initWeakReference =
    UPCALL_METHOD(loader, "java/lang/ref/WeakReference", "<init>",
                  "(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V",
                  ACC_VIRTUAL);
  initWeakReference->setNative();
  
  JavaMethod* initSoftReference =
    UPCALL_METHOD(loader, "java/lang/ref/SoftReference", "<init>",
                  "(Ljava/lang/Object;)V",
                  ACC_VIRTUAL);
  initSoftReference->setNative();
  
  initSoftReference =
    UPCALL_METHOD(loader, "java/lang/ref/SoftReference", "<init>",
                  "(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V",
                  ACC_VIRTUAL);
  initSoftReference->setNative();
  
  JavaMethod* initPhantomReference =
    UPCALL_METHOD(loader, "java/lang/ref/PhantomReference", "<init>",
                  "(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V",
                  ACC_VIRTUAL);
  initPhantomReference->setNative();
}
Handle<Value> JSWrapper( const Arguments &args )
{
	JavaMethod* m = (JavaMethod*) External::Unwrap(args.Data());
	m->Invoke(args);
	return Undefined();
}
bool JavaInstance::invokeMethod(const char* methodName, const NPVariant* args, uint32_t count, NPVariant* resultValue)
{
    int i;
    jvalue *jArgs;
    JavaMethod *method = 0;

    VOID_TO_NPVARIANT(*resultValue);

    MethodList methodList = getClass()->methodsNamed(methodName);

    size_t numMethods = methodList.size();
    
    // Try to find a good match for the overloaded method.  The 
    // fundamental problem is that JavaScript doesn have the
    // notion of method overloading and Java does.  We could 
    // get a bit more sophisticated and attempt to does some
    // type checking as we as checking the number of parameters.
    JavaMethod *aMethod;
    for (size_t methodIndex = 0; methodIndex < numMethods; methodIndex++) {
        aMethod = methodList[methodIndex];
        if (aMethod->numParameters() == count) {
            method = aMethod;
            break;
        }
    }
    if (method == 0) {
        LOGW("unable to find an appropiate method\n");
        return false;
    }
    
    const JavaMethod *jMethod = static_cast<const JavaMethod*>(method);
    
    if (count > 0) {
        jArgs = (jvalue *)malloc (count * sizeof(jvalue));
    }
    else
        jArgs = 0;
        
    for (i = 0; i < count; i++) {
        JavaParameter* aParameter = jMethod->parameterAt(i);
        jArgs[i] = convertNPVariantToJValue(args[i], aParameter->getJNIType(), aParameter->type());
    }
        
    jvalue result;

    // The following code can be conditionally removed once we have a Tiger update that
    // contains the new Java plugin.  It is needed for builds prior to Tiger.
    {    
        jobject obj = getLocalRef();
        switch (jMethod->JNIReturnType()){
            case void_type:
                callJNIMethodIDA<void>(obj, jMethod->methodID(obj), jArgs);
                break;            
            case object_type:
                result.l = callJNIMethodIDA<jobject>(obj, jMethod->methodID(obj), jArgs);
                break;
            case boolean_type:
                result.z = callJNIMethodIDA<jboolean>(obj, jMethod->methodID(obj), jArgs);
                break;
            case byte_type:
                result.b = callJNIMethodIDA<jbyte>(obj, jMethod->methodID(obj), jArgs);
                break;
            case char_type:
                result.c = callJNIMethodIDA<jchar>(obj, jMethod->methodID(obj), jArgs);
                break;            
            case short_type:
                result.s = callJNIMethodIDA<jshort>(obj, jMethod->methodID(obj), jArgs);
                break;
            case int_type:
                result.i = callJNIMethodIDA<jint>(obj, jMethod->methodID(obj), jArgs);
                break;
            
            case long_type:
                result.j = callJNIMethodIDA<jlong>(obj, jMethod->methodID(obj), jArgs);
                break;
            case float_type:
                result.f = callJNIMethodIDA<jfloat>(obj, jMethod->methodID(obj), jArgs);
                break;
            case double_type:
                result.d = callJNIMethodIDA<jdouble>(obj, jMethod->methodID(obj), jArgs);
                break;
            case invalid_type:
            default:
                break;
        }
        getJNIEnv()->DeleteLocalRef(obj);
    }
    
    convertJValueToNPVariant(result, jMethod->JNIReturnType(), jMethod->returnType(), resultValue);
    free (jArgs);

    return true;
}
extern "C" void* j3ResolveVirtualStub(JavaObject* obj) {
  llvm_gcroot(obj, 0);
  JavaThread *th = JavaThread::get();
  UserCommonClass* cl = JavaObject::getClass(obj);
  void* result = NULL;
  
  // Lookup the caller of this class.
  vmkit::StackWalker Walker(th);
  ++Walker; // Remove the stub.
  vmkit::FrameInfo* FI = Walker.get();
  assert(FI->Metadata != NULL && "Wrong stack trace");
  JavaMethod* meth = (JavaMethod*)FI->Metadata;

  // Lookup the method info in the constant pool of the caller.
  uint16 ctpIndex = meth->lookupCtpIndex(FI);
  assert(ctpIndex && "No constant pool index");
  JavaConstantPool* ctpInfo = meth->classDef->getConstantPool();
  CommonClass* ctpCl = 0;
  const UTF8* utf8 = 0;
  Signdef* sign = 0;
  JavaMethod* origMeth = 0;
  ctpInfo->infoOfMethod(ctpIndex, ACC_VIRTUAL, ctpCl, origMeth);

  ctpInfo->resolveMethod(ctpIndex, ctpCl, utf8, sign);
  assert(cl->isSubclassOf(ctpCl) && "Wrong call object");
  UserClass* lookup = cl->isArray() ? cl->super : cl->asClass();
  JavaMethod* Virt = lookup->lookupMethod(utf8, sign->keyName, false, true, 0);

  if (isAbstract(Virt->access)) {
    JavaThread::get()->getJVM()->abstractMethodError(Virt->classDef, Virt->name);
  }

  // Compile the found method.
  result = Virt->compiledPtr(lookup);

  // Update the virtual table.
  assert(lookup->isResolved() && "Class not resolved");
  assert(lookup->isInitializing() && "Class not ready");
  assert(lookup->virtualVT && "Class has no VT");
  assert(lookup->virtualTableSize > Virt->offset && 
         "The method's offset is greater than the virtual table size");
  ((void**)obj->getVirtualTable())[Virt->offset] = result;
  
  if (isInterface(origMeth->classDef->access)) {
    InterfaceMethodTable* IMT = cl->virtualVT->IMT;
    uint32_t index = InterfaceMethodTable::getIndex(Virt->name, Virt->type);
    if ((IMT->contents[index] & 1) == 0) {
      IMT->contents[index] = (word_t)result;
    } else { 
      JavaMethod* Imeth = 
        ctpCl->asClass()->lookupInterfaceMethodDontThrow(utf8, sign->keyName);
      assert(Imeth && "Method not in hierarchy?");
      word_t* table = (word_t*)(IMT->contents[index] & ~1);
      uint32 i = 0;
      while (table[i] != (word_t)Imeth) { i += 2; }
      table[i + 1] = (word_t)result;
    }
  }

  return result;
}