Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
jvalue JPStringType::convertToJava(HostRef* obj)
{
	TRACE_IN("JPStringType::convertToJava");
	JPCleaner cleaner;
	jvalue v;
	
	if (JPEnv::getHost()->isNone(obj))
	{
		v.l = NULL;
		return v;
	}
	
	if (JPEnv::getHost()->isWrapper(obj))
	{
		return JPEnv::getHost()->getWrapperValue(obj);
	}

	if (JPEnv::getHost()->isObject(obj))
	{
		JPObject* o = JPEnv::getHost()->asObject(obj);

		JPClass* oc = o->getClass();
		if (oc->getName().getSimpleName() == "java.lang.String")
		{
			v.l = o->getObject();
			return v;
		}
	}

	JCharString wstr = JPEnv::getHost()->stringAsJCharString(obj);

	jchar* jstr = new jchar[wstr.length()+1];
	jstr[wstr.length()] = 0;
	for (size_t i = 0; i < wstr.length(); i++)
	{
		jstr[i] = (jchar)wstr[i];  
	}
	jstring res = JPEnv::getJava()->NewString(jstr, (jint)wstr.length());
	delete[] jstr;
	
	v.l = res;
	
	return v;
	TRACE_OUT;
}
Exemplo n.º 3
0
jobject JPPrimitiveType::convertToJavaObject(HostRef* obj)
{
	JPCleaner cleaner;
	JPTypeName tname = getObjectType();
	JPClass* c = JPTypeManager::findClass(tname);

	jclass jc = c->getClass();
	cleaner.addLocal(jc);

	vector<HostRef*> args(1);
	args[0] = obj;

	JPObject* o = c->newInstance(args);
	jobject res = o->getObject();
	delete o;

	return res;
}
Exemplo n.º 4
0
EMatchType JPStringType::canConvertToJava(HostRef* obj)
{
	TRACE_IN("JPStringType::canConvertToJava");
	JPCleaner cleaner;

	if (obj == NULL || JPEnv::getHost()->isNone(obj))
	{
		return _implicit;
	}

	if (JPEnv::getHost()->isString(obj))
	{
		return _exact;
	}
	
	if (JPEnv::getHost()->isWrapper(obj))
	{
		JPTypeName name = JPEnv::getHost()->getWrapperTypeName(obj);

		if (name.getType() == JPTypeName::_string)
		{
			return _exact;
		}
	}

	if (JPEnv::getHost()->isObject(obj))
	{
		JPObject* o = JPEnv::getHost()->asObject(obj);

		JPClass* oc = o->getClass();
		if (oc->getName().getSimpleName() == "java.lang.String")
		{
			return _exact;
		}
	}
	return _none;
	TRACE_OUT;
}
Exemplo n.º 5
0
jvalue JPClass::convertToJava(HostRef* obj)
{
	jvalue res;
	JPCleaner cleaner;

	res.l = NULL;

	// assume it is convertible;
	if (JPEnv::getHost()->isNone(obj))
	{
		res.l = NULL;
	}

	string simpleName = m_Name.getSimpleName();	
	if (JPEnv::getHost()->isInt(obj) && (simpleName == "java.lang.Byte" || simpleName == "java.lang.Short" ||
	    simpleName == "java.lang.Integer"))
	{
		return buildObjectWrapper(obj);
	}    	
	
	if ((JPEnv::getHost()->isInt(obj) || JPEnv::getHost()->isLong(obj)) && simpleName == "java.lang.Long" && JPEnv::getHost()->isLong(obj))
	{
		return buildObjectWrapper(obj);
	}
	
	if (JPEnv::getHost()->isFloat(obj) && (simpleName == "java.lang.Float" || simpleName == "java.lang.Double"))
	{
		if (JPEnv::getHost()->isFloat(obj))
		{
			return buildObjectWrapper(obj);
		}
	}    	

	if (JPEnv::getHost()->isString(obj))
	{
		JPTypeName name = JPTypeName::fromSimple("java.lang.String");
		JPType* type = JPTypeManager::getType(name);
		return type->convertToJava(obj);
	}

	if (JPEnv::getHost()->isObject(obj))
	{
		JPObject* ref = JPEnv::getHost()->asObject(obj);
		res.l = ref->getObject();
	}

	if (JPEnv::getHost()->isProxy(obj))
	{
		JPProxy* proxy = JPEnv::getHost()->asProxy(obj);
		res.l = proxy->getProxy();
	}

	if (JPEnv::getHost()->isWrapper(obj))
	{
		res = JPEnv::getHost()->getWrapperValue(obj);
	}

	if (JPEnv::getHost()->isInt(obj))
	{
		JPTypeName tname = JPTypeName::fromType(JPTypeName::_int);
		JPType* t = JPTypeManager::getType(tname);
		res.l = t->convertToJavaObject(obj);
	}
	
	if (JPEnv::getHost()->isLong(obj))
	{
		JPTypeName tname = JPTypeName::fromType(JPTypeName::_long);
		JPType* t = JPTypeManager::getType(tname);
		res.l = t->convertToJavaObject(obj);
	}
	
	if (JPEnv::getHost()->isFloat(obj))
	{
		JPTypeName tname = JPTypeName::fromType(JPTypeName::_double);
		JPType* t = JPTypeManager::getType(tname);
		res.l = t->convertToJavaObject(obj);
	}

	if (JPEnv::getHost()->isBoolean(obj))
	{
		JPTypeName tname = JPTypeName::fromType(JPTypeName::_boolean);
		JPType* t = JPTypeManager::getType(tname);
		res.l = t->convertToJavaObject(obj);
	}

	if (JPEnv::getHost()->isArray(obj) && simpleName == "java.lang.Object")
	{
		JPArray* a = JPEnv::getHost()->asArray(obj);
		res = a->getValue();		
	}

	return res;
}
Exemplo n.º 6
0
EMatchType JPClass::canConvertToJava(HostRef* obj)
{
	if (JPEnv::getHost()->isNone(obj))
	{
		return _implicit;
	}

	JPCleaner cleaner;

	string simpleName = m_Name.getSimpleName();	
	
	if (simpleName == "java.lang.Byte" || simpleName == "java.lang.Short" ||
	    simpleName == "java.lang.Integer")
	{
		if (JPEnv::getHost()->isInt(obj))
		{
			return _explicit;
		}
	}    	
	
	if (simpleName == "java.lang.Long" && JPEnv::getHost()->isLong(obj))
	{
		return _explicit;
	}
	
	if (simpleName == "java.lang.Float" || simpleName == "java.lang.Double")
	{
		if (JPEnv::getHost()->isFloat(obj))
		{
			return _explicit;
		}
	}    	
		
	if (JPEnv::getHost()->isObject(obj))
	{
		JPObject* o = JPEnv::getHost()->asObject(obj);

		JPClass* oc = o->getClass();

		if (oc == this)
		{
			// hey, this is me! :)
			return _exact;
		}

		if (JPEnv::getJava()->IsAssignableFrom(oc->m_Class, m_Class))
		{
			return _implicit;
		}
	}

	if (JPEnv::getHost()->isProxy(obj))
	{
		JPProxy* proxy = JPEnv::getHost()->asProxy(obj);
		// Check if any of the interfaces matches ...
		vector<jclass> itf = proxy->getInterfaces();
		for (unsigned int i = 0; i < itf.size(); i++)
		{
			if (JPEnv::getJava()->IsAssignableFrom(itf[i], m_Class))
			{
				return _implicit;
			}
		}
	}

	if (JPEnv::getHost()->isWrapper(obj))
	{
		JPTypeName o = JPEnv::getHost()->getWrapperTypeName(obj);

		if (o.getSimpleName() == m_Name.getSimpleName())
		{
			return _exact;
		}
	}

	if (m_Name.getSimpleName() == "java.lang.Object")
	{
		// arrays are objects
		if (JPEnv::getHost()->isArray(obj))
		{
			return _implicit;
		}
		
		// Strings are objects too
		if (JPEnv::getHost()->isString(obj))
		{
			return _implicit;
		}
		
		// Class are objects too
		if (JPEnv::getHost()->isClass(obj) || JPEnv::getHost()->isArrayClass(obj))
		{
			return _implicit;
		}

		// Let'a allow primitives (int, long, float and boolean) to convert implicitly too ...
		if (JPEnv::getHost()->isInt(obj))
		{
			return _implicit;
		}
		
		if (JPEnv::getHost()->isLong(obj))
		{
			return _implicit;
		}
		
		if (JPEnv::getHost()->isFloat(obj))
		{
			return _implicit;
		}

		if (JPEnv::getHost()->isBoolean(obj))
		{
			return _implicit;
		}
	}

	return _none;
}
Exemplo n.º 7
0
JNIEXPORT jobject JNICALL Java_jpype_JPypeInvocationHandler_hostInvoke(
	JNIEnv *env, jclass clazz, jstring name, 
	jlong hostObj, jobjectArray args, 
	jobjectArray types, jclass returnType)
{
	TRACE_IN("Java_jpype_JPypeInvocationHandler_hostInvoke");

	void* callbackState = JPEnv::getHost()->prepareCallbackBegin();

	JPCleaner cleaner;

	try {
		string cname = JPJni::asciiFromJava(name);

		HostRef* hostObjRef = (HostRef*)hostObj;

		HostRef* callable = JPEnv::getHost()->getCallableFrom(hostObjRef, cname);
		cleaner.add(callable);

		if (callable == NULL || callable->isNull() || JPEnv::getHost()->isNone(callable))
		{
			JPEnv::getJava()->ThrowNew(JPJni::s_NoSuchMethodErrorClass, cname.c_str());
			JPEnv::getHost()->prepareCallbackFinish(callbackState);
			return NULL;
		}
					
		// convert the arguments into a python list
		jsize argLen = JPEnv::getJava()->GetArrayLength(types);
		vector<HostRef*> hostArgs;
		std::vector<JPTypeName> argTypes;

		for (jsize j = 0; j < argLen; j++)
		{
			jclass c = (jclass)JPEnv::getJava()->GetObjectArrayElement(types, j);
			cleaner.addLocal(c);
			JPTypeName tn = JPJni::getName(c);
			argTypes.push_back(tn);
		}

		for (int i = 0; i < argLen; i++)
		{
			jobject obj = JPEnv::getJava()->GetObjectArrayElement(args, i);
			cleaner.addLocal(obj);
			JPTypeName t = argTypes[i];

			jvalue v;
			v.l = obj;

			HostRef* o = JPTypeManager::getType(t)->asHostObjectFromObject(v);
			cleaner.add(o);
			hostArgs.push_back(o);

		}

		HostRef* returnValue = JPEnv::getHost()->callObject(callable, hostArgs);
		cleaner.add(returnValue);

		JPTypeName returnT = JPJni::getName(returnType);

		if (returnValue == NULL || returnValue->isNull() || JPEnv::getHost()->isNone(returnValue))
		{
			if (returnT.getType() != JPTypeName::_void && returnT.getType() < JPTypeName::_object)
			{
				JPEnv::getJava()->ThrowNew(JPJni::s_RuntimeExceptionClass, "Return value is None when it cannot be");
				JPEnv::getHost()->prepareCallbackFinish(callbackState);
				return NULL;
			}
		}

		if (returnT.getType() == JPTypeName::_void)
		{
			JPEnv::getHost()->prepareCallbackFinish(callbackState);
			return NULL;
		}

		JPType* rt = JPTypeManager::getType(returnT);
		if (rt->canConvertToJava(returnValue) == _none)
		{
			JPEnv::getJava()->ThrowNew(JPJni::s_RuntimeExceptionClass, "Return value is not compatible with required type.");
			JPEnv::getHost()->prepareCallbackFinish(callbackState);
			return NULL;
		}
		
		jobject returnObj = rt->convertToJavaObject(returnValue);

		JPEnv::getHost()->prepareCallbackFinish(callbackState);

		return returnObj;

	}
	catch(HostException* ex) 
	{ 
		JPEnv::getHost()->clearError();
		if (JPEnv::getHost()->isJavaException(ex))
		{
			JPCleaner cleaner;
			HostRef* javaExcRef = JPEnv::getHost()->getJavaException(ex);
			JPObject* javaExc = JPEnv::getHost()->asObject(javaExcRef);
			cleaner.add(javaExcRef);
			jobject obj = javaExc->getObject();
			cleaner.addLocal(obj);
			JPEnv::getJava()->Throw((jthrowable)obj);
		}
		else
		{
			JPEnv::getJava()->ThrowNew(JPJni::s_RuntimeExceptionClass, "Python exception thrown");
		}
	} 
	catch(JavaException*) 
	{ 
		cerr << "Java exception at " << __FILE__ << ":" << __LINE__ << endl; 
	}
	catch(JPypeException* ex)
	{
		JPEnv::getJava()->ThrowNew(JPJni::s_RuntimeExceptionClass, ex->getMsg());
	}

	JPEnv::getHost()->prepareCallbackFinish(callbackState);

	return NULL;

	TRACE_OUT;
}