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); }
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); }
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); }
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); } }
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; }
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; }