Changed JNI to use standard caller ID mechanism.

This commit is contained in:
jfrijters 2010-01-06 14:28:38 +00:00
Родитель d0a44066a2
Коммит 34bf6475f7
5 изменённых файлов: 33 добавлений и 42 удалений

Просмотреть файл

@ -1180,6 +1180,17 @@ namespace IKVM.Internal
Debug.Assert(wrapper.GetClassLoader() == this);
return this == friend.GetClassLoader();
}
#if !STATIC_COMPILER
internal static ClassLoaderWrapper FromCallerID(object callerID)
{
#if FIRST_PASS
return null;
#else
return GetClassLoaderWrapper(((ikvm.@internal.CallerID)callerID).getCallerClassLoader());
#endif
}
#endif
}
class GenericClassLoader : ClassLoaderWrapper

Просмотреть файл

@ -4462,7 +4462,7 @@ namespace IKVM.Internal
// are public and so we can get away with replacing all other types with object.
argTypes[i + instance] = (args[i].IsPrimitive || args[i].IsGhost || args[i].IsNonPrimitiveValueType) ? args[i].TypeAsSignatureType : typeof(object);
}
argTypes[argTypes.Length - 1] = typeof(RuntimeMethodHandle);
argTypes[argTypes.Length - 1] = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.CallerID").TypeAsSignatureType;
Type retType = (mw.ReturnType.IsPrimitive || mw.ReturnType.IsGhost || mw.ReturnType.IsNonPrimitiveValueType) ? mw.ReturnType.TypeAsSignatureType : typeof(object);
MethodBuilder mb = tb.DefineMethod("method", MethodAttributes.Public | MethodAttributes.Static, retType, argTypes);
AttributeHelper.HideFromJava(mb);
@ -4472,7 +4472,7 @@ namespace IKVM.Internal
{
ilGenerator.Emit(OpCodes.Ldarg, (short)i);
}
ilGenerator.Emit(OpCodes.Ldtoken, (MethodInfo)mw.GetMethod());
context.EmitCallerID(ilGenerator);
ilGenerator.Emit(OpCodes.Call, mb);
if (!mw.ReturnType.IsPrimitive && !mw.ReturnType.IsGhost && !mw.ReturnType.IsNonPrimitiveValueType)
{
@ -4528,7 +4528,7 @@ namespace IKVM.Internal
}
else
{
ilGenerator.Emit(OpCodes.Ldtoken, (MethodInfo)mw.GetMethod());
context.EmitCallerID(ilGenerator);
}
ilGenerator.Emit(OpCodes.Ldstr, classFile.Name.Replace('.', '/'));
ilGenerator.Emit(OpCodes.Ldstr, m.Name);
@ -4543,7 +4543,7 @@ namespace IKVM.Internal
}
else
{
ilGenerator.Emit(OpCodes.Ldtoken, (MethodInfo)mw.GetMethod());
context.EmitCallerID(ilGenerator);
}
ilGenerator.Emit(OpCodes.Call, enterLocalRefStruct);
LocalBuilder jnienv = ilGenerator.DeclareLocal(Types.IntPtr);

Просмотреть файл

@ -160,14 +160,14 @@ namespace IKVM.Runtime
{
private JNIEnv* pJNIEnv;
private JNIEnv.ManagedJNIEnv env;
private RuntimeMethodHandle prevMethod;
private ikvm.@internal.CallerID prevCallerID;
private object[] quickLocals;
private int quickLocalIndex;
private int prevLocalRefSlot;
internal ClassLoaderWrapper Enter(ClassLoaderWrapper loader)
{
Enter(new RuntimeMethodHandle());
Enter((ikvm.@internal.CallerID)null);
ClassLoaderWrapper prev = env.classLoader;
env.classLoader = loader;
return prev;
@ -179,7 +179,7 @@ namespace IKVM.Runtime
Leave();
}
public IntPtr Enter(RuntimeMethodHandle method)
public IntPtr Enter(ikvm.@internal.CallerID callerID)
{
pJNIEnv = TlsHack.pJNIEnv;
if(pJNIEnv == null)
@ -187,8 +187,8 @@ namespace IKVM.Runtime
pJNIEnv = JNIEnv.CreateJNIEnv();
}
env = pJNIEnv->GetManagedJNIEnv();
prevMethod = env.currentMethod;
env.currentMethod = method;
prevCallerID = env.callerID;
env.callerID = callerID;
object[][] localRefs = env.localRefs;
prevLocalRefSlot = env.localRefSlot;
env.localRefSlot++;
@ -209,7 +209,7 @@ namespace IKVM.Runtime
public void Leave()
{
env.currentMethod = prevMethod;
env.callerID = prevCallerID;
Exception x = env.pendingException;
env.pendingException = null;
object[][] localRefs = env.localRefs;
@ -235,10 +235,9 @@ namespace IKVM.Runtime
}
}
public static IntPtr GetFuncPtr(RuntimeMethodHandle method, string clazz, string name, string sig)
public static IntPtr GetFuncPtr(ikvm.@internal.CallerID callerID, string clazz, string name, string sig)
{
MethodBase mb = MethodBase.GetMethodFromHandle(method);
ClassLoaderWrapper loader = ClassLoaderWrapper.GetWrapperFromType(mb.DeclaringType).GetClassLoader();
ClassLoaderWrapper loader = ClassLoaderWrapper.FromCallerID(callerID);
int sp = 0;
for(int i = 1; sig[i] != ')'; i++)
{
@ -1100,7 +1099,7 @@ namespace IKVM.Runtime
internal sealed class ManagedJNIEnv
{
internal ClassLoaderWrapper classLoader;
internal RuntimeMethodHandle currentMethod;
internal ikvm.@internal.CallerID callerID;
internal object[][] localRefs;
internal int localRefSlot;
internal Exception pendingException;
@ -1332,10 +1331,9 @@ namespace IKVM.Runtime
private static ClassLoaderWrapper FindNativeMethodClassLoader(JNIEnv* pEnv)
{
ManagedJNIEnv env = pEnv->GetManagedJNIEnv();
if(env.currentMethod.Value != IntPtr.Zero)
if(env.callerID != null)
{
MethodBase mb = MethodBase.GetMethodFromHandle(env.currentMethod);
return ClassLoaderWrapper.GetWrapperFromType(mb.DeclaringType).GetClassLoader();
return ClassLoaderWrapper.FromCallerID(env.callerID);
}
if(env.classLoader != null)
{
@ -1441,7 +1439,7 @@ namespace IKVM.Runtime
{
wrapper.Finish();
java.lang.reflect.Constructor cons = (java.lang.reflect.Constructor)mw.ToMethodOrConstructor(false);
exception = (Exception)cons.newInstance(new object[] { StringFromOEM(msg) }, (ikvm.@internal.CallerID)JVM.CreateCallerID(env.currentMethod));
exception = (Exception)cons.newInstance(new object[] { StringFromOEM(msg) }, env.callerID);
rc = JNI_OK;
}
catch(RetargetableJavaException x)
@ -1706,12 +1704,7 @@ namespace IKVM.Runtime
}
try
{
MethodBase caller = null;
if(env.currentMethod.Value != IntPtr.Zero)
{
caller = MethodBase.GetMethodFromHandle(env.currentMethod);
}
return MethodWrapper.FromCookie(methodID).InvokeJNI(pEnv->UnwrapRef(obj), argarray, nonVirtual, caller);
return MethodWrapper.FromCookie(methodID).InvokeJNI(pEnv->UnwrapRef(obj), argarray, nonVirtual, env.callerID);
}
catch(java.lang.reflect.InvocationTargetException x)
{

Просмотреть файл

@ -115,7 +115,7 @@ namespace IKVM.Internal
internal static MemberWrapper FromCookieImpl(IntPtr cookie)
{
return (MemberWrapper)((GCHandle)cookie).Target;
return (MemberWrapper)GCHandle.FromIntPtr(cookie).Target;
}
internal TypeWrapper DeclaringType
@ -770,7 +770,7 @@ namespace IKVM.Internal
#if !STATIC_COMPILER
[HideFromJava]
internal object InvokeJNI(object obj, object[] args, bool nonVirtual, MethodBase callerID)
internal object InvokeJNI(object obj, object[] args, bool nonVirtual, object callerID)
{
#if FIRST_PASS
return null;
@ -807,7 +807,7 @@ namespace IKVM.Internal
try
{
ResolveMethod();
InvokeArgsProcessor proc = new InvokeArgsProcessor(this, method, obj, UnboxArgs(args), ikvm.@internal.CallerID.create(callerID));
InvokeArgsProcessor proc = new InvokeArgsProcessor(this, method, obj, UnboxArgs(args), (ikvm.@internal.CallerID)callerID);
object o = method.Invoke(proc.GetObj(), proc.GetArgs());
TypeWrapper retType = this.ReturnType;
if (!retType.IsUnloadable && retType.IsGhost)
@ -853,7 +853,7 @@ namespace IKVM.Internal
invokenonvirtualCache.Add(this, acc);
}
}
object val = acc.invoke(obj, args, ikvm.@internal.CallerID.create(callerID));
object val = acc.invoke(obj, args, (ikvm.@internal.CallerID)callerID);
if (this.ReturnType.IsPrimitive && this.ReturnType != PrimitiveTypeWrapper.VOID)
{
val = JVM.Unbox(val);
@ -870,7 +870,7 @@ namespace IKVM.Internal
acc = (sun.reflect.MethodAccessor)IKVM.NativeCode.sun.reflect.ReflectionFactory.newMethodAccessor(null, method);
method.setMethodAccessor(acc);
}
object val = acc.invoke(obj, args, ikvm.@internal.CallerID.create(callerID));
object val = acc.invoke(obj, args, (ikvm.@internal.CallerID)callerID);
if (this.ReturnType.IsPrimitive && this.ReturnType != PrimitiveTypeWrapper.VOID)
{
val = JVM.Unbox(val);

Просмотреть файл

@ -430,19 +430,6 @@ namespace IKVM.Internal
}
#endif
#if !STATIC_COMPILER
// helper for JNI (which doesn't have access to core library internals)
internal static object CreateCallerID(RuntimeMethodHandle method)
{
#if FIRST_PASS
return null;
#else
return ikvm.@internal.CallerID.create(MethodBase.GetMethodFromHandle(method));
#endif
}
#endif
#if !STATIC_COMPILER
// helper for JNI (which doesn't have access to core library internals)
internal static object NewDirectByteBuffer(long address, int capacity)