vector<JPTypeName> getParameterTypes(jobject o, bool isConstructor) { JPCleaner cleaner; vector<JPTypeName> args; jobjectArray types ; if (isConstructor) { types = (jobjectArray)JPEnv::getJava()->CallObjectMethod(o, getConstructorParameterTypesID); } else { types = (jobjectArray)JPEnv::getJava()->CallObjectMethod(o, getParameterTypesID); } cleaner.addLocal(types); int len = JPEnv::getJava()->GetArrayLength(types); for (int i = 0; i < len; i++) { jclass c = (jclass)JPEnv::getJava()->GetObjectArrayElement(types, i); cleaner.addLocal(c); JPTypeName name = getName(c); args.push_back(name); } return args; }
JPObject* JPMethodOverload::invokeConstructor(jclass claz, vector<HostRef*>& arg) { TRACE_IN("JPMethodOverload::invokeConstructor"); size_t len = arg.size(); JPCleaner cleaner; JPMallocCleaner<jvalue> v(len); for (unsigned int i = 0; i < len; i++) { HostRef* obj = arg[i]; // TODO the following can easily be optimized ... or at least cached JPType* t = JPTypeManager::getType(m_Arguments[i]); v[i] = t->convertToJava(obj); if (t->isObjectType()) { cleaner.addLocal(v[i].l); } } jvalue val; val.l = JPEnv::getJava()->NewObjectA(claz, m_MethodID, v.borrow()); cleaner.addLocal(val.l); TRACE1("Object created"); JPTypeName name = JPJni::getName(claz); return new JPObject(name, val.l); TRACE_OUT; }
void JPypeJavaException::errorOccurred() { TRACE_IN("PyJavaException::errorOccurred"); JPCleaner cleaner; jthrowable th = JPEnv::getJava()->ExceptionOccurred(); cleaner.addLocal(th); JPEnv::getJava()->ExceptionClear(); jclass ec = JPJni::getClass(th); JPTypeName tn = JPJni::getName(ec); JPClass* jpclass = JPTypeManager::findClass(tn); cleaner.addLocal(ec); PyObject* jexclass = hostEnv->getJavaShadowClass(jpclass); HostRef* pyth = hostEnv->newObject(new JPObject(tn, th)); cleaner.add(pyth); PyObject* args = JPySequence::newTuple(2); PyObject* arg2 = JPySequence::newTuple(1); JPySequence::setItem(arg2, 0, args); Py_DECREF(args); JPySequence::setItem(args, 0, hostEnv->m_SpecialConstructorKey); JPySequence::setItem(args, 1, (PyObject*)pyth->data()); PyObject* pyexclass = JPyObject::getAttrString(jexclass, "PYEXC"); Py_DECREF(jexclass); JPyErr::setObject(pyexclass, arg2); Py_DECREF(arg2); Py_DECREF(pyexclass); TRACE_OUT; }
PyObject* JPypeModule::synchronized(PyObject* obj, PyObject* args) { JPCleaner cleaner; TRACE_IN("synchronized"); try { PyObject* o; JPyArg::parseTuple(args, "O!", &PyCObject_Type, &o); string desc = (char*)JPyCObject::getDesc(o); jobject obj; if (desc == "JPObject") { JPObject* jpo = (JPObject*)JPyCObject::asVoidPtr(o); obj = jpo->getObject(); cleaner.addLocal(obj); } else if (desc == "JPClass") { JPClass* jpo = (JPClass*)JPyCObject::asVoidPtr(o); obj = jpo->getClass(); cleaner.addLocal(obj); } else if (desc == "JPArray") { JPArray* jpo = (JPArray*)JPyCObject::asVoidPtr(o); obj = jpo->getObject(); cleaner.addLocal(obj); } else if (desc == "JPArrayClass") { JPArrayClass* jpo = (JPArrayClass*)JPyCObject::asVoidPtr(o); obj = jpo->getClass(); cleaner.addLocal(obj); } else if (hostEnv->isWrapper(o) && hostEnv->getWrapperTypeName(o).isObjectType()) { obj = hostEnv->getWrapperValue(o).l; cleaner.addLocal(obj); } // TODO proxy else { RAISE(JPypeException, "method only accepts object values."); } PyJPMonitor* c = PyJPMonitor::alloc(new JPMonitor(obj)); return (PyObject*)c; } PY_STANDARD_CATCH; PyErr_Clear(); Py_INCREF(Py_None); return Py_None; TRACE_OUT; }
PyObject* PyJPField::getInstanceAttribute(PyObject* o, PyObject* arg) { TRACE_IN("getInstanceAttribute"); JPCleaner cleaner; try { PyJPField* self = (PyJPField*)o; PyObject* jo; JPyArg::parseTuple(arg, "O!", &PyCapsule_Type, &jo); JPObject* obj = (JPObject*)JPyCObject::asVoidPtr(jo); jobject jobj = obj->getObject(); cleaner.addLocal(jobj); HostRef* res = self->m_Field->getAttribute(jobj); return detachRef(res); } PY_STANDARD_CATCH return NULL; TRACE_OUT; }
PyObject* PyJPField::setInstanceAttribute(PyObject* o, PyObject* arg) { JPCleaner cleaner; try { PyJPField* self = (PyJPField*)o; PyObject* jo; PyObject* value; JPyArg::parseTuple(arg, "O!O", &PyCapsule_Type, &jo, &value); JPObject* obj = (JPObject*)JPyCObject::asVoidPtr(jo); HostRef* ref = new HostRef(value); cleaner.add(ref); jobject jobj = obj->getObject(); cleaner.addLocal(jobj); self->m_Field->setAttribute(jobj, ref); Py_INCREF(Py_None); return Py_None; } PY_STANDARD_CATCH return NULL; }
void startJPypeReferenceQueue(bool useJavaThread) { JPCleaner cleaner; JPypeReferenceQueueClass = (jclass)JPEnv::getJava()->NewGlobalRef(JPEnv::getJava()->FindClass("jpype/ref/JPypeReferenceQueue")); JPypeReferenceQueueConstructorMethod = JPEnv::getJava()->GetMethodID(JPypeReferenceQueueClass, "<init>", "()V"); JPypeReferenceQueueRegisterMethod = JPEnv::getJava()->GetMethodID(JPypeReferenceQueueClass, "registerRef", "(Ljpype/ref/JPypeReference;J)V"); JPypeReferenceQueueStartMethod = JPEnv::getJava()->GetMethodID(JPypeReferenceQueueClass, "startManaging", "()V"); JPypeReferenceQueueRunMethod = JPEnv::getJava()->GetMethodID(JPypeReferenceQueueClass, "run", "()V"); JPypeReferenceQueueStopMethod = JPEnv::getJava()->GetMethodID(JPypeReferenceQueueClass, "stop", "()V"); JPypeReferenceClass = (jclass)JPEnv::getJava()->NewGlobalRef(JPEnv::getJava()->FindClass("jpype/ref/JPypeReference")); JPypeReferenceConstructorMethod = JPEnv::getJava()->GetMethodID(JPypeReferenceClass, "<init>", "(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;)V"); jobject obj = JPEnv::getJava()->NewObject(JPypeReferenceQueueClass, JPypeReferenceQueueConstructorMethod); cleaner.addLocal(obj); JPEnv::getJava()->setReferenceQueue(obj); if (useJavaThread) { JPEnv::getJava()->CallVoidMethod(obj, JPypeReferenceQueueStartMethod); } else { JPEnv::getJava()->CallVoidMethod(obj, JPypeReferenceQueueRunMethod); } }
void JPField::setStaticAttribute(HostRef* val) { TRACE_IN("JPField::setStaticAttribute"); if (m_IsFinal) { stringstream err; err << "Field " << m_Name << " is read-only"; RAISE(JPypeException, err.str().c_str()); } JPType* type = JPTypeManager::getType(m_Type); if (type->canConvertToJava(val) <= _explicit) { stringstream err; err << "unable to convert to " << type->getName().getSimpleName(); RAISE(JPypeException, err.str().c_str()); } JPCleaner cleaner; jclass claz = m_Class->getClass(); cleaner.addLocal(claz); type->setStaticValue(claz, m_FieldID, val); TRACE_OUT; }
HostRef* JPMethodOverload::invokeStatic(vector<HostRef*>& arg) { TRACE_IN("JPMethodOverload::invokeStatic"); JPCleaner cleaner; size_t len = arg.size(); JPMallocCleaner<jvalue> v(len); JPMallocCleaner<JPType*> types(len); for (unsigned int i = 0; i < len; i++) { HostRef* obj = arg[i]; types[i] = JPTypeManager::getType(m_Arguments[i]); v[i] = types[i]->convertToJava(obj); if (types[i]->isObjectType()) { cleaner.addLocal(v[i].l); } } jclass claz = m_Class->getClass(); cleaner.addGlobal(claz); JPType* retType = JPTypeManager::getType(m_ReturnType); return retType->invokeStatic(claz, m_MethodID, v.borrow()); TRACE_OUT; }
void JPProxy::init() { TRACE_IN("JPProxy::init"); // build the proxy class ... jobject cl = JPJni::getSystemClassLoader(); JPCleaner cleaner; jclass handler = JPEnv::getJava()->DefineClass("jpype/JPypeInvocationHandler", cl, JPypeInvocationHandler, getJPypeInvocationHandlerLength()); handlerClass = (jclass)JPEnv::getJava()->NewGlobalRef(handler); cleaner.addLocal(handler); JNINativeMethod method[1]; method[0].name = (char*) "hostInvoke"; method[0].signature =(char*) "(Ljava/lang/String;J[Ljava/lang/Object;[Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/Object;"; method[0].fnPtr = (void*) &Java_jpype_JPypeInvocationHandler_hostInvoke; hostObjectID = JPEnv::getJava()->GetFieldID(handler, "hostObject", "J"); invocationHandlerConstructorID = JPEnv::getJava()->GetMethodID(handler, "<init>", "()V"); JPEnv::getJava()->RegisterNatives(handlerClass, method, 1); // Not quite the right area ... but I;m doing similar here already so let's register the other classes too jclass reference = JPEnv::getJava()->DefineClass("jpype/ref/JPypeReference", cl, JPypeReference, getJPypeReferenceLength()); jclass referenceQueue = JPEnv::getJava()->DefineClass("jpype/ref/JPypeReferenceQueue", cl, JPypeReferenceQueue, getJPypeReferenceQueueLength()); referenceClass = (jclass)JPEnv::getJava()->NewGlobalRef(reference); referenceQueueClass = (jclass)JPEnv::getJava()->NewGlobalRef(referenceQueue); //Required due to bug in jvm //See: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6493522 jmethodID refQConstr = JPEnv::getJava()->GetMethodID(referenceQueue, "<init>", "()V"); cleaner.addLocal(reference); cleaner.addLocal(referenceQueue); JNINativeMethod method2[1]; method2[0].name = (char*) "removeHostReference"; method2[0].signature = (char*) "(J)V"; method2[0].fnPtr = (void*)&Java_jpype_ref_JPypeReferenceQueue_removeHostReference; JPEnv::getJava()->RegisterNatives(referenceQueueClass, method2, 1); TRACE_OUT; }
string getMessage(jthrowable th) { JPCleaner cleaner; jstring jstr = (jstring)JPEnv::getJava()->CallObjectMethod(th, getMessageID); cleaner.addLocal(jstr); return asciiFromJava(jstr); }
JPTypeName getReturnType(jobject o) { JPCleaner cleaner; jclass c = (jclass)JPEnv::getJava()->CallObjectMethod(o, getReturnTypeID); cleaner.addLocal(c); return getName(c); }
string getMemberName(jobject o) { JPCleaner cleaner; jstring name = (jstring)JPEnv::getJava()->CallObjectMethod(o, getMemberNameID); cleaner.addLocal(name); string simpleName = asciiFromJava(name); return simpleName; }
jarray JPObjectType::newArrayInstance(int sz) { JPCleaner cleaner; jclass c = getClass(); cleaner.addLocal(c); return JPEnv::getJava()->NewObjectArray(sz, c, NULL); }
void JPObjectType::setArrayItem(jarray a, int ndx, HostRef* val) { jobjectArray array = (jobjectArray)a; JPCleaner cleaner; jvalue v = convertToJava(val); cleaner.addLocal(v.l); JPEnv::getJava()->SetObjectArrayElement(array, ndx, v.l); }
JPTypeName getType(jobject fld) { TRACE_IN("getType"); JPCleaner cleaner; jclass c = (jclass)JPEnv::getJava()->CallObjectMethod(fld, getTypeID); cleaner.addLocal(c); return getName(c); TRACE_OUT; }
void JPObjectType::setStaticValue(jclass c, jfieldID fid, HostRef* obj) { TRACE_IN("JPObjectType::setStaticValue"); JPCleaner cleaner; jobject val = convertToJava(obj).l; cleaner.addLocal(val); JPEnv::getJava()->SetStaticObjectField(c, fid, val); TRACE_OUT; }
JPArray* JPArrayClass::newInstance(int length) { JPCleaner cleaner; jarray array = m_ComponentType->newArrayInstance(length); cleaner.addLocal(array); JPArray* res = new JPArray(getName(), array); return res; }
JPTypeName getClassName(jobject o) { if (o == NULL) { return JPTypeName::fromSimple("java.lang.Object"); } JPCleaner cleaner; jclass c = getClass(o); cleaner.addLocal(c); return getName(c); }
HostRef* JPField::getStaticAttribute() { TRACE_IN("JPField::getStaticAttribute"); JPType* type = JPTypeManager::getType(m_Type); JPCleaner cleaner; jclass claz = m_Class->getClass(); cleaner.addLocal(claz); return type->getStaticValue(claz, m_FieldID, m_Type); TRACE_OUT; }
void JPEnv::registerRef(HostRef* ref, HostRef* targetRef) { TRACE_IN("JPEnv::registerRef"); JPObject* objRef = s_Host->asObject(ref); JPCleaner cleaner; TRACE1("A"); jobject srcObject = objRef->getObject(); cleaner.addLocal(srcObject); JPJni::registerRef(s_Java->getReferenceQueue(), srcObject, (jlong)targetRef->copy()); TRACE_OUT; TRACE1("B"); }
bool JPClass::isSubclass(JPClass* o) { JPCleaner cleaner; jclass jo = o->getClass(); cleaner.addLocal(jo); if (JPEnv::getJava()->IsAssignableFrom(m_Class, jo)) { return true; } return false; }
string getStackTrace(jthrowable th) { JPCleaner cleaner; jobject strWriter = JPEnv::getJava()->NewObject(stringWriterClass, stringWriterID); cleaner.addLocal(strWriter); jvalue v; v.l = strWriter; jobject printWriter = JPEnv::getJava()->NewObjectA(printWriterClass, printWriterID, &v); cleaner.addLocal(printWriter); v.l = printWriter; JPEnv::getJava()->CallVoidMethodA(th, printStackTraceID, &v); JPEnv::getJava()->CallVoidMethod(printWriter, flushID); jstring res = toString(strWriter); cleaner.addLocal(res); return asciiFromJava(res); }
jobject JPProxy::getProxy() { JPCleaner cleaner; jobject cl = JPJni::getSystemClassLoader(); cleaner.addLocal(cl); jvalue v[3]; v[0].l = cl; v[1].l = m_Interfaces; v[2].l = m_Handler; jobject res = JPEnv::getJava()->CallStaticObjectMethodA(JPJni::s_ProxyClass, JPJni::s_NewProxyInstanceID, v); return res; }
HostRef* JPObjectType::getInstanceValue(jobject c, jfieldID fid, JPTypeName& tgtType) { TRACE_IN("JPObjectType::getInstanceValue"); JPCleaner cleaner; jobject r = JPEnv::getJava()->GetObjectField(c, fid); cleaner.addLocal(r); jvalue v; v.l = r; JPTypeName name = JPJni::getClassName(v.l); JPType* type = JPTypeManager::getType(name); return type->asHostObject(v); TRACE_OUT; }
void JPObjectType::setArrayRange(jarray a, int start, int length, vector<HostRef*>& vals) { jobjectArray array = (jobjectArray)a; JPCleaner cleaner; jvalue v; for (int i = 0; i < length; i++) { HostRef* pv = vals[i]; v = convertToJava(pv); cleaner.addLocal(v.l); JPEnv::getJava()->SetObjectArrayElement(array, i+start, v.l); } }
vector<jclass> getInterfaces(jclass clazz) { JPCleaner cleaner; jobjectArray interfaces = (jobjectArray)JPEnv::getJava()->CallObjectMethod(clazz, getInterfacesID); cleaner.addLocal(interfaces); int len = JPEnv::getJava()->GetArrayLength(interfaces); vector<jclass> res; for (int i = 0; i < len; i++) { jclass c = (jclass)JPEnv::getJava()->GetObjectArrayElement(interfaces, i); res.push_back(c); } return res; }
vector<jobject> getMethods(jclass clazz) { JPCleaner cleaner; jobjectArray methods = (jobjectArray)JPEnv::getJava()->CallObjectMethod(clazz, getMethodsID); cleaner.addLocal(methods); int len = JPEnv::getJava()->GetArrayLength(methods); vector<jobject> res; for (int i = 0; i < len; i++) { jobject c = JPEnv::getJava()->GetObjectArrayElement(methods, i); res.push_back(c); } return res; }
HostRef* JPMethodOverload::invokeInstance(vector<HostRef*>& args) { TRACE_IN("JPMethodOverload::invokeInstance"); HostRef* res; { JPCleaner cleaner; // Arg 0 is "this" HostRef* self = args[0]; JPObject* selfObj = JPEnv::getHost()->asObject(self); size_t len = args.size(); JPMallocCleaner<jvalue> v(len-1); for (unsigned int i = 1; i < len; i++) { HostRef* obj = args[i]; JPType* type = JPTypeManager::getType(m_Arguments[i]); v[i-1] = type->convertToJava(obj); // below seems not to be necessary, since jvalues are clean by jpmalloccleaner // if (type->isObjectType()) // { // //TODO : investigate: this is not valid for either local or global ref // // add hostref to garbage collection // cleaner.add(v[i-1].l); // } } JPType* retType = JPTypeManager::getType(m_ReturnType); jobject c = selfObj->getObject(); cleaner.addLocal(c); jclass clazz = m_Class->getClass(); cleaner.addGlobal(clazz); res = retType->invoke(c, clazz, m_MethodID, v.borrow()); TRACE1("Call finished"); } TRACE1("Call successfull"); return res; TRACE_OUT; }
HostRef* JPObjectType::invokeStatic(jclass claz, jmethodID mth, jvalue* val) { TRACE_IN("JPObjectType::invokeStatic"); JPCleaner cleaner; jobject res = JPEnv::getJava()->CallStaticObjectMethodA(claz, mth, val); cleaner.addLocal(res); jvalue v; v.l = res; JPTypeName name = JPJni::getClassName(v.l); JPType* type = JPTypeManager::getType(name); return type->asHostObject(v); TRACE_OUT; }