/* JVM-Bridge -- bridge from FP languages and others to the Java VM Copyright (C) 2001 Ashley Yakeley This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "Debug.hpp" #include "JVMBridge.h" #include "ExecuteFunctionControl.h" const char* kExecuteFunctionClassName = EXECUTEFUNCTION_CLASSNAME; template struct Attrs { typedef T (*Function) (JNIEnv* env,jvaluelist args); }; inline jvaluelist ToValueList(COpaqueAddress vl) { return reinterpret_cast(vl); } // destroys argsVal template inline T executeFunction(JNIEnv* env,COpaqueAddress functionVal,COpaqueAddress argsVal) { typedef typename Attrs::Function Function; Function function = reinterpret_cast(functionVal); jvaluelist args = ToValueList(argsVal); T result; { DebugBlockTracer tracer("calling function"); result = (*function)(env,args); } JVMBRIDGEFUNC(DestroyValueList)(args); return result; } // destroys argsVal template <> inline void executeFunction(JNIEnv* env,COpaqueAddress functionVal,COpaqueAddress argsVal) { typedef Attrs::Function Function; Function function = reinterpret_cast(functionVal); jvaluelist args = ToValueList(argsVal); { DebugBlockTracer tracer("calling function"); (*function)(env,args); } JVMBRIDGEFUNC(DestroyValueList)(args); } extern "C" COpaqueAddress JNICALL createValueList (JNIEnv*,jclass) { DebugBlockTracer tracer("native createValueList"); return reinterpret_cast(JVMBRIDGEFUNC(CreateValueList)()); } uintptr_t JVMBRIDGEFUNC(ConvertCallback) (void* addr) { DebugBlockTracer tracer("ConvertCallback"); DebugShowPointer(addr,"addr"); return reinterpret_cast(addr); } extern "C" void JNICALL destroyValueList (JNIEnv*,jclass,COpaqueAddress vl) { DebugBlockTracer tracer("native destroyValueList"); JVMBRIDGEFUNC(DestroyValueList)(ToValueList(vl)); } extern "C" void JNICALL addToValueList_Boolean (JNIEnv*,jclass,COpaqueAddress vl,jboolean v) { DebugBlockTracer tracer("native addToValueList __IZ"); DebugShowBoolean(v,"adding"); JVMBRIDGEFUNC(AddBooleanToValueList)(ToValueList(vl),v); } extern "C" void JNICALL addToValueList_Byte (JNIEnv*,jclass,COpaqueAddress vl,jbyte v) { DebugBlockTracer tracer("native addToValueList __IB"); DebugShowByte(v,"adding"); JVMBRIDGEFUNC(AddByteToValueList)(ToValueList(vl),v); } extern "C" void JNICALL addToValueList_Char (JNIEnv*,jclass,COpaqueAddress vl,jchar v) { DebugBlockTracer tracer("native addToValueList __IC"); DebugShowChar(v,"adding"); JVMBRIDGEFUNC(AddCharToValueList)(ToValueList(vl),v); } extern "C" void JNICALL addToValueList_Short (JNIEnv*,jclass,COpaqueAddress vl,jshort v) { DebugBlockTracer tracer("native addToValueList __IS"); DebugShowShort(v,"adding"); JVMBRIDGEFUNC(AddShortToValueList)(ToValueList(vl),v); } extern "C" void JNICALL addToValueList_Int (JNIEnv*,jclass,COpaqueAddress vl,jint v) { DebugBlockTracer tracer("native addToValueList __II"); DebugShowInt(v,"adding"); JVMBRIDGEFUNC(AddIntToValueList)(ToValueList(vl),v); } extern "C" void JNICALL addToValueList_Long (JNIEnv*,jclass,COpaqueAddress vl,jlong v) { DebugBlockTracer tracer("native addToValueList __IJ"); DebugShowLong(v,"adding"); JVMBRIDGEFUNC(AddLongToValueList)(ToValueList(vl),v); } extern "C" void JNICALL addToValueList_Float (JNIEnv*,jclass,COpaqueAddress vl,jfloat v) { DebugBlockTracer tracer("native addToValueList __IF"); DebugShowFloat(v,"adding"); JVMBRIDGEFUNC(AddFloatToValueList)(ToValueList(vl),v); } extern "C" void JNICALL addToValueList_Double (JNIEnv*,jclass,COpaqueAddress vl,jdouble v) { DebugBlockTracer tracer("native addToValueList __ID"); DebugShowDouble(v,"adding"); JVMBRIDGEFUNC(AddDoubleToValueList)(ToValueList(vl),v); } extern "C" void JNICALL addToValueList_Object (JNIEnv* env,jclass,COpaqueAddress vl,jobject v) { DebugBlockTracer tracer("native addToValueList __ILjava_lang_Object_2"); DebugShowRef(v,"local"); jobject globalRef = env->NewGlobalRef(v); DebugShowRef(globalRef,"adding"); JVMBRIDGEFUNC(AddObjectToValueList)(ToValueList(vl),globalRef); } #define DebugOpaqueAddress DebugShowInt // destroys argsVal extern "C" void JNICALL executeVoidFunctionNow (JNIEnv* env,jclass,COpaqueAddress functionVal,COpaqueAddress argsVal) { DebugBlockTracer tracer("native executeVoidFunctionNow"); DebugOpaqueAddress(functionVal,"function"); DebugOpaqueAddress(argsVal,"args"); executeFunction(env,functionVal,argsVal); } // destroys argsVal extern "C" jboolean JNICALL executeBooleanFunctionNow (JNIEnv* env,jclass,COpaqueAddress functionVal,COpaqueAddress argsVal) { DebugBlockTracer tracer("native executeBooleanFunctionNow"); DebugOpaqueAddress(functionVal,"function"); DebugOpaqueAddress(argsVal,"args"); return executeFunction(env,functionVal,argsVal); } // destroys argsVal extern "C" jbyte JNICALL executeByteFunctionNow (JNIEnv* env,jclass,COpaqueAddress functionVal,COpaqueAddress argsVal) { DebugBlockTracer tracer("native executeByteFunctionNow"); DebugOpaqueAddress(functionVal,"function"); DebugOpaqueAddress(argsVal,"args"); return executeFunction(env,functionVal,argsVal); } // destroys argsVal extern "C" jchar JNICALL executeCharFunctionNow (JNIEnv* env,jclass,COpaqueAddress functionVal,COpaqueAddress argsVal) { DebugBlockTracer tracer("native executeCharFunctionNow"); DebugOpaqueAddress(functionVal,"function"); DebugOpaqueAddress(argsVal,"args"); return executeFunction(env,functionVal,argsVal); } // destroys argsVal extern "C" jshort JNICALL executeShortFunctionNow (JNIEnv* env,jclass,COpaqueAddress functionVal,COpaqueAddress argsVal) { DebugBlockTracer tracer("native executeShortFunctionNow"); DebugOpaqueAddress(functionVal,"function"); DebugOpaqueAddress(argsVal,"args"); return executeFunction(env,functionVal,argsVal); } // destroys argsVal extern "C" jint JNICALL executeIntFunctionNow (JNIEnv* env,jclass,COpaqueAddress functionVal,COpaqueAddress argsVal) { DebugBlockTracer tracer("native executeIntFunctionNow"); DebugOpaqueAddress(functionVal,"function"); DebugOpaqueAddress(argsVal,"args"); return executeFunction(env,functionVal,argsVal); } // destroys argsVal extern "C" jlong JNICALL executeLongFunctionNow (JNIEnv* env,jclass,COpaqueAddress functionVal,COpaqueAddress argsVal) { DebugBlockTracer tracer("native executeLongFunctionNow"); DebugOpaqueAddress(functionVal,"function"); DebugOpaqueAddress(argsVal,"args"); return executeFunction(env,functionVal,argsVal); } // destroys argsVal extern "C" jfloat JNICALL executeFloatFunctionNow (JNIEnv* env,jclass,COpaqueAddress functionVal,COpaqueAddress argsVal) { DebugBlockTracer tracer("native executeFloatFunctionNow"); DebugOpaqueAddress(functionVal,"function"); DebugOpaqueAddress(argsVal,"args"); return executeFunction(env,functionVal,argsVal); } // destroys argsVal extern "C" jdouble JNICALL executeDoubleFunctionNow (JNIEnv* env,jclass,COpaqueAddress functionVal,COpaqueAddress argsVal) { DebugBlockTracer tracer("native executeDoubleFunctionNow"); DebugOpaqueAddress(functionVal,"function"); DebugOpaqueAddress(argsVal,"args"); return executeFunction(env,functionVal,argsVal); } // destroys argsVal extern "C" jobject JNICALL executeObjectFunctionNow (JNIEnv* env,jclass,COpaqueAddress functionVal,COpaqueAddress argsVal) { DebugBlockTracer tracer("native executeObjectFunctionNow"); DebugOpaqueAddress(functionVal,"function"); DebugOpaqueAddress(argsVal,"args"); return executeFunction(env,functionVal,argsVal); } FreeFunction gFree; extern "C" void JNICALL freeFunctionNow (JNIEnv* env,jclass,COpaqueAddress functionVal) { DebugBlockTracer tracer("native freeFunctionNow"); DebugOpaqueAddress(functionVal,"function"); gFree(reinterpret_cast(functionVal)); } const jint nNativeBindings=22; template inline void* cast_f(T x) { return reinterpret_cast(reinterpret_cast(x)); // hack to avoid warning } const JNINativeMethod nativeBindings[] = { {"createValueList","()" SigOpaqueAddress,cast_f(&createValueList)}, {"destroyValueList","(" SigOpaqueAddress ")V",cast_f(&destroyValueList)}, {"addToValueList","(" SigOpaqueAddress "Z)V",cast_f(&addToValueList_Boolean)}, {"addToValueList","(" SigOpaqueAddress "B)V",cast_f(&addToValueList_Byte)}, {"addToValueList","(" SigOpaqueAddress "C)V",cast_f(&addToValueList_Char)}, {"addToValueList","(" SigOpaqueAddress "S)V",cast_f(&addToValueList_Short)}, {"addToValueList","(" SigOpaqueAddress "I)V",cast_f(&addToValueList_Int)}, {"addToValueList","(" SigOpaqueAddress "J)V",cast_f(&addToValueList_Long)}, {"addToValueList","(" SigOpaqueAddress "F)V",cast_f(&addToValueList_Float)}, {"addToValueList","(" SigOpaqueAddress "D)V",cast_f(&addToValueList_Double)}, {"addToValueList","(" SigOpaqueAddress "Ljava/lang/Object;)V",cast_f(&addToValueList_Object)}, {"executeVoidFunctionNow" ,"(" SigOpaqueAddress SigOpaqueAddress ")V",cast_f(&executeVoidFunctionNow)}, {"executeBooleanFunctionNow","(" SigOpaqueAddress SigOpaqueAddress ")Z",cast_f(&executeBooleanFunctionNow)}, {"executeByteFunctionNow" ,"(" SigOpaqueAddress SigOpaqueAddress ")B",cast_f(&executeByteFunctionNow)}, {"executeCharFunctionNow" ,"(" SigOpaqueAddress SigOpaqueAddress ")C",cast_f(&executeCharFunctionNow)}, {"executeShortFunctionNow" ,"(" SigOpaqueAddress SigOpaqueAddress ")S",cast_f(&executeShortFunctionNow)}, {"executeIntFunctionNow" ,"(" SigOpaqueAddress SigOpaqueAddress ")I",cast_f(&executeIntFunctionNow)}, {"executeLongFunctionNow" ,"(" SigOpaqueAddress SigOpaqueAddress ")J",cast_f(&executeLongFunctionNow)}, {"executeFloatFunctionNow" ,"(" SigOpaqueAddress SigOpaqueAddress ")F",cast_f(&executeFloatFunctionNow)}, {"executeDoubleFunctionNow" ,"(" SigOpaqueAddress SigOpaqueAddress ")D",cast_f(&executeDoubleFunctionNow)}, {"executeObjectFunctionNow" ,"(" SigOpaqueAddress SigOpaqueAddress ")Ljava/lang/Object;",cast_f(&executeObjectFunctionNow)}, {"freeFunctionNow","(" SigOpaqueAddress ")V",cast_f(&freeFunctionNow)} }; inline void RegisterExecuteFunctionBindings(JNIEnv* env) { DebugBlockTracer tracer("RegisterExecuteFunctionBindings"); jclass theClass = env->FindClass(kExecuteFunctionClassName); if (!theClass) ErrorMessage("Failed to load Java Class %s: Wrong CLASSPATH?\n", kExecuteFunctionClassName); jint result = env->RegisterNatives(theClass,nativeBindings,nNativeBindings); DebugShowInt(result,"result"); if (result) { env->ExceptionDescribe(); ErrorMessage("Failed in JNI RegisterNatives for Class %s: %x\n", kExecuteFunctionClassName, result); } InfoDebugMessage("RegisterExecuteFunctionBindings succeeded\n"); }; void JVMBridge_StartExecuteFunction(JNIEnv* env,FreeFunction freeF) { RegisterExecuteFunctionBindings(env); gFree = freeF; };