зеркало из https://github.com/mono/ikvm-fork.git
Changed JNI reflection to be based on Java reflection (where possible).
This commit is contained in:
Родитель
316dd359eb
Коммит
6bce58f1bc
|
@ -1405,7 +1405,8 @@ namespace IKVM.Runtime
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
wrapper.Finish();
|
wrapper.Finish();
|
||||||
exception = (Exception)mw.InvokeJNI(null, new object[] { StringFromOEM(msg) }, false, null);
|
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(pEnv->currentMethod));
|
||||||
rc = JNI_OK;
|
rc = JNI_OK;
|
||||||
}
|
}
|
||||||
catch(RetargetableJavaException x)
|
catch(RetargetableJavaException x)
|
||||||
|
@ -1635,28 +1636,28 @@ namespace IKVM.Runtime
|
||||||
switch(sig[i])
|
switch(sig[i])
|
||||||
{
|
{
|
||||||
case 'Z':
|
case 'Z':
|
||||||
argarray[i] = args[i].z != JNI_FALSE;
|
argarray[i] = java.lang.Boolean.valueOf(args[i].z != JNI_FALSE);
|
||||||
break;
|
break;
|
||||||
case 'B':
|
case 'B':
|
||||||
argarray[i] = args[i].b;
|
argarray[i] = java.lang.Byte.valueOf((byte)args[i].b);
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
argarray[i] = (char)args[i].c;
|
argarray[i] = java.lang.Character.valueOf((char)args[i].c);
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
argarray[i] = args[i].s;
|
argarray[i] = java.lang.Short.valueOf(args[i].s);
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
argarray[i] = args[i].i;
|
argarray[i] = java.lang.Integer.valueOf(args[i].i);
|
||||||
break;
|
break;
|
||||||
case 'J':
|
case 'J':
|
||||||
argarray[i] = args[i].j;
|
argarray[i] = java.lang.Long.valueOf(args[i].j);
|
||||||
break;
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
argarray[i] = args[i].f;
|
argarray[i] = java.lang.Float.valueOf(args[i].f);
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
argarray[i] = args[i].d;
|
argarray[i] = java.lang.Double.valueOf(args[i].d);
|
||||||
break;
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
argarray[i] = pEnv->UnwrapRef(args[i].l);
|
argarray[i] = pEnv->UnwrapRef(args[i].l);
|
||||||
|
@ -2003,120 +2004,99 @@ namespace IKVM.Runtime
|
||||||
return FindFieldID(pEnv, clazz, name, sig, false);
|
return FindFieldID(pEnv, clazz, name, sig, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetFieldValue(jfieldID cookie, object obj, object val)
|
private static sun.reflect.FieldAccessor GetFieldAccessor(jfieldID cookie)
|
||||||
{
|
{
|
||||||
try
|
return (sun.reflect.FieldAccessor)FieldWrapper.FromCookie(cookie).GetFieldAccessorJNI();
|
||||||
{
|
|
||||||
FieldWrapper.FromCookie(cookie).SetValue(obj, val);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
Debug.Assert(false);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static object GetFieldValue(jfieldID cookie, object obj)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return FieldWrapper.FromCookie(cookie).GetValue(obj);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
Debug.Assert(false);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jobject GetObjectField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
internal static jobject GetObjectField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return pEnv->MakeLocalRef(GetFieldValue(fieldID, pEnv->UnwrapRef(obj)));
|
return pEnv->MakeLocalRef(GetFieldAccessor(fieldID).get(pEnv->UnwrapRef(obj)));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jboolean GetBooleanField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
internal static jboolean GetBooleanField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return ((bool)GetFieldValue(fieldID, pEnv->UnwrapRef(obj))) ? JNI_TRUE : JNI_FALSE;
|
return GetFieldAccessor(fieldID).getBoolean(pEnv->UnwrapRef(obj)) ? JNI_TRUE : JNI_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jbyte GetByteField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
internal static jbyte GetByteField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return (jbyte)(byte)GetFieldValue(fieldID, pEnv->UnwrapRef(obj));
|
return (jbyte)GetFieldAccessor(fieldID).getByte(pEnv->UnwrapRef(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jchar GetCharField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
internal static jchar GetCharField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return (jchar)(char)GetFieldValue(fieldID, pEnv->UnwrapRef(obj));
|
return (jchar)GetFieldAccessor(fieldID).getChar(pEnv->UnwrapRef(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jshort GetShortField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
internal static jshort GetShortField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return (jshort)(short)GetFieldValue(fieldID, pEnv->UnwrapRef(obj));
|
return (jshort)GetFieldAccessor(fieldID).getShort(pEnv->UnwrapRef(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jint GetIntField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
internal static jint GetIntField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return (jint)(int)GetFieldValue(fieldID, pEnv->UnwrapRef(obj));
|
return (jint)GetFieldAccessor(fieldID).getInt(pEnv->UnwrapRef(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jlong GetLongField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
internal static jlong GetLongField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return (jlong)(long)GetFieldValue(fieldID, pEnv->UnwrapRef(obj));
|
return (jlong)GetFieldAccessor(fieldID).getLong(pEnv->UnwrapRef(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jfloat GetFloatField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
internal static jfloat GetFloatField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return (jfloat)(float)GetFieldValue(fieldID, pEnv->UnwrapRef(obj));
|
return (jfloat)GetFieldAccessor(fieldID).getFloat(pEnv->UnwrapRef(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jdouble GetDoubleField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
internal static jdouble GetDoubleField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return (jdouble)(double)GetFieldValue(fieldID, pEnv->UnwrapRef(obj));
|
return (jdouble)GetFieldAccessor(fieldID).getDouble(pEnv->UnwrapRef(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetObjectField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jobject val)
|
internal static void SetObjectField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jobject val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, pEnv->UnwrapRef(obj), pEnv->UnwrapRef(val));
|
GetFieldAccessor(fieldID).set(pEnv->UnwrapRef(obj), pEnv->UnwrapRef(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetBooleanField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jboolean val)
|
internal static void SetBooleanField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jboolean val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, pEnv->UnwrapRef(obj), val != JNI_FALSE);
|
GetFieldAccessor(fieldID).setBoolean(pEnv->UnwrapRef(obj), val != JNI_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetByteField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jbyte val)
|
internal static void SetByteField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jbyte val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, pEnv->UnwrapRef(obj), (byte)val);
|
GetFieldAccessor(fieldID).setByte(pEnv->UnwrapRef(obj), (byte)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetCharField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jchar val)
|
internal static void SetCharField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jchar val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, pEnv->UnwrapRef(obj), (char)val);
|
GetFieldAccessor(fieldID).setChar(pEnv->UnwrapRef(obj), (char)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetShortField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jshort val)
|
internal static void SetShortField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jshort val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, pEnv->UnwrapRef(obj), (short)val);
|
GetFieldAccessor(fieldID).setShort(pEnv->UnwrapRef(obj), (short)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetIntField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jint val)
|
internal static void SetIntField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jint val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, pEnv->UnwrapRef(obj), (int)val);
|
GetFieldAccessor(fieldID).setInt(pEnv->UnwrapRef(obj), (int)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetLongField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jlong val)
|
internal static void SetLongField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jlong val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, pEnv->UnwrapRef(obj), (long)val);
|
GetFieldAccessor(fieldID).setLong(pEnv->UnwrapRef(obj), (long)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetFloatField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jfloat val)
|
internal static void SetFloatField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jfloat val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, pEnv->UnwrapRef(obj), (float)val);
|
GetFieldAccessor(fieldID).setFloat(pEnv->UnwrapRef(obj), (float)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetDoubleField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jdouble val)
|
internal static void SetDoubleField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jdouble val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, pEnv->UnwrapRef(obj), (double)val);
|
GetFieldAccessor(fieldID).setDouble(pEnv->UnwrapRef(obj), (double)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jmethodID GetStaticMethodID(JNIEnv* pEnv, jclass clazz, byte* name, byte* sig)
|
internal static jmethodID GetStaticMethodID(JNIEnv* pEnv, jclass clazz, byte* name, byte* sig)
|
||||||
|
@ -2221,92 +2201,92 @@ namespace IKVM.Runtime
|
||||||
|
|
||||||
internal static jobject GetStaticObjectField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
internal static jobject GetStaticObjectField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return pEnv->MakeLocalRef(GetFieldValue(fieldID, null));
|
return pEnv->MakeLocalRef(GetFieldAccessor(fieldID).get(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jboolean GetStaticBooleanField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
internal static jboolean GetStaticBooleanField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return ((bool)GetFieldValue(fieldID, null)) ? JNI_TRUE : JNI_FALSE;
|
return GetFieldAccessor(fieldID).getBoolean(null) ? JNI_TRUE : JNI_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jbyte GetStaticByteField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
internal static jbyte GetStaticByteField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return (jbyte)(byte)GetFieldValue(fieldID, null);
|
return (jbyte)GetFieldAccessor(fieldID).getByte(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jchar GetStaticCharField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
internal static jchar GetStaticCharField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return (jchar)(char)GetFieldValue(fieldID, null);
|
return (jchar)GetFieldAccessor(fieldID).getChar(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jshort GetStaticShortField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
internal static jshort GetStaticShortField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return (jshort)(short)GetFieldValue(fieldID, null);
|
return (jshort)GetFieldAccessor(fieldID).getShort(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jint GetStaticIntField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
internal static jint GetStaticIntField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return (jint)(int)GetFieldValue(fieldID, null);
|
return (jint)GetFieldAccessor(fieldID).getInt(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jlong GetStaticLongField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
internal static jlong GetStaticLongField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return (jlong)(long)GetFieldValue(fieldID, null);
|
return (jlong)GetFieldAccessor(fieldID).getLong(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jfloat GetStaticFloatField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
internal static jfloat GetStaticFloatField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return (jfloat)(float)GetFieldValue(fieldID, null);
|
return (jfloat)GetFieldAccessor(fieldID).getFloat(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jdouble GetStaticDoubleField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
internal static jdouble GetStaticDoubleField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
||||||
{
|
{
|
||||||
return (jdouble)(double)GetFieldValue(fieldID, null);
|
return (jdouble)GetFieldAccessor(fieldID).getDouble(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetStaticObjectField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jobject val)
|
internal static void SetStaticObjectField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jobject val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, null, pEnv->UnwrapRef(val));
|
GetFieldAccessor(fieldID).set(null, pEnv->UnwrapRef(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetStaticBooleanField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jboolean val)
|
internal static void SetStaticBooleanField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jboolean val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, null, val != JNI_FALSE);
|
GetFieldAccessor(fieldID).setBoolean(null, val != JNI_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetStaticByteField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jbyte val)
|
internal static void SetStaticByteField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jbyte val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, null, (byte)val);
|
GetFieldAccessor(fieldID).setByte(null, (byte)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetStaticCharField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jchar val)
|
internal static void SetStaticCharField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jchar val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, null, (char)val);
|
GetFieldAccessor(fieldID).setChar(null, (char)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetStaticShortField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jshort val)
|
internal static void SetStaticShortField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jshort val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, null, (short)val);
|
GetFieldAccessor(fieldID).setShort(null, (short)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetStaticIntField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jint val)
|
internal static void SetStaticIntField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jint val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, null, (int)val);
|
GetFieldAccessor(fieldID).setInt(null, (int)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetStaticLongField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jlong val)
|
internal static void SetStaticLongField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jlong val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, null, (long)val);
|
GetFieldAccessor(fieldID).setLong(null, (long)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetStaticFloatField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jfloat val)
|
internal static void SetStaticFloatField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jfloat val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, null, (float)val);
|
GetFieldAccessor(fieldID).setFloat(null, (float)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetStaticDoubleField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jdouble val)
|
internal static void SetStaticDoubleField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jdouble val)
|
||||||
{
|
{
|
||||||
SetFieldValue(fieldID, null, (double)val);
|
GetFieldAccessor(fieldID).setDouble(null, (double)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jstring NewString(JNIEnv* pEnv, jchar* unicode, int len)
|
internal static jstring NewString(JNIEnv* pEnv, jchar* unicode, int len)
|
||||||
|
|
|
@ -29,6 +29,7 @@ using System.Reflection.Emit;
|
||||||
#endif
|
#endif
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using IKVM.Attributes;
|
using IKVM.Attributes;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace IKVM.Internal
|
namespace IKVM.Internal
|
||||||
{
|
{
|
||||||
|
@ -278,6 +279,7 @@ namespace IKVM.Internal
|
||||||
abstract class MethodWrapper : MemberWrapper
|
abstract class MethodWrapper : MemberWrapper
|
||||||
{
|
{
|
||||||
#if !STATIC_COMPILER && !FIRST_PASS
|
#if !STATIC_COMPILER && !FIRST_PASS
|
||||||
|
private static Dictionary<MethodWrapper, sun.reflect.MethodAccessor> invokenonvirtualCache;
|
||||||
private volatile object reflectionMethod;
|
private volatile object reflectionMethod;
|
||||||
#endif
|
#endif
|
||||||
internal static readonly MethodWrapper[] EmptyArray = new MethodWrapper[0];
|
internal static readonly MethodWrapper[] EmptyArray = new MethodWrapper[0];
|
||||||
|
@ -704,9 +706,122 @@ namespace IKVM.Internal
|
||||||
#if FIRST_PASS
|
#if FIRST_PASS
|
||||||
return null;
|
return null;
|
||||||
#else
|
#else
|
||||||
return Invoke(obj, args, nonVirtual, ikvm.@internal.CallerID.create(callerID));
|
if (ReferenceEquals(Name, StringConstants.INIT))
|
||||||
|
{
|
||||||
|
java.lang.reflect.Constructor cons = (java.lang.reflect.Constructor)ToMethodOrConstructor(false);
|
||||||
|
if (obj == null)
|
||||||
|
{
|
||||||
|
sun.reflect.ConstructorAccessor acc = cons.getConstructorAccessor();
|
||||||
|
if (acc == null)
|
||||||
|
{
|
||||||
|
acc = reflectionFactory.newConstructorAccessor(cons);
|
||||||
|
cons.setConstructorAccessor(acc);
|
||||||
|
}
|
||||||
|
return acc.newInstance(args);
|
||||||
|
}
|
||||||
|
else if (method is MethodInfo)
|
||||||
|
{
|
||||||
|
Debug.Assert(method.IsStatic);
|
||||||
|
// we're dealing with a constructor on a remapped type, if obj is supplied, it means
|
||||||
|
// that we should call the constructor on an already existing instance, but that isn't
|
||||||
|
// possible with remapped types
|
||||||
|
// the type of this exception is a bit random (note that this can only happen through JNI reflection)
|
||||||
|
throw new java.lang.IncompatibleClassChangeError(string.Format("Remapped type {0} doesn't support constructor invocation on an existing instance", DeclaringType.Name));
|
||||||
|
}
|
||||||
|
else if (!method.DeclaringType.IsInstanceOfType(obj))
|
||||||
|
{
|
||||||
|
// we're trying to initialize an existing instance of a remapped type
|
||||||
|
throw new NotSupportedException("Unable to partially construct object of type " + obj.GetType().FullName + " to type " + method.DeclaringType.FullName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
InvokeArgsProcessor proc = new InvokeArgsProcessor(this, method, obj, UnboxArgs(args), ikvm.@internal.CallerID.create(callerID));
|
||||||
|
object o = method.Invoke(proc.GetObj(), proc.GetArgs());
|
||||||
|
TypeWrapper retType = this.ReturnType;
|
||||||
|
if (!retType.IsUnloadable && retType.IsGhost)
|
||||||
|
{
|
||||||
|
o = retType.GhostRefField.GetValue(o);
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
catch (ArgumentException x1)
|
||||||
|
{
|
||||||
|
throw new java.lang.IllegalArgumentException(x1.Message);
|
||||||
|
}
|
||||||
|
catch (TargetInvocationException x)
|
||||||
|
{
|
||||||
|
throw new java.lang.reflect.InvocationTargetException(ikvm.runtime.Util.mapException(x.InnerException));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (nonVirtual
|
||||||
|
&& !this.IsStatic
|
||||||
|
&& !this.IsPrivate
|
||||||
|
&& !this.IsAbstract
|
||||||
|
&& !this.IsFinal
|
||||||
|
&& !this.DeclaringType.IsFinal)
|
||||||
|
{
|
||||||
|
if (this.DeclaringType.IsRemapped)
|
||||||
|
{
|
||||||
|
ResolveMethod();
|
||||||
|
return InvokeImpl(method, obj, UnboxArgs(args), true, ikvm.@internal.CallerID.create(callerID));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (invokenonvirtualCache == null)
|
||||||
|
{
|
||||||
|
Interlocked.CompareExchange(ref invokenonvirtualCache, new Dictionary<MethodWrapper, sun.reflect.MethodAccessor>(), null);
|
||||||
|
}
|
||||||
|
sun.reflect.MethodAccessor acc;
|
||||||
|
lock (invokenonvirtualCache)
|
||||||
|
{
|
||||||
|
if (!invokenonvirtualCache.TryGetValue(this, out acc))
|
||||||
|
{
|
||||||
|
acc = new IKVM.NativeCode.sun.reflect.ReflectionFactory.FastMethodAccessorImpl((java.lang.reflect.Method)ToMethodOrConstructor(false), true);
|
||||||
|
invokenonvirtualCache.Add(this, acc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object val = acc.invoke(obj, args, ikvm.@internal.CallerID.create(callerID));
|
||||||
|
if (this.ReturnType.IsPrimitive && this.ReturnType != PrimitiveTypeWrapper.VOID)
|
||||||
|
{
|
||||||
|
val = JVM.Unbox(val);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
java.lang.reflect.Method method = (java.lang.reflect.Method)ToMethodOrConstructor(false);
|
||||||
|
sun.reflect.MethodAccessor acc = method.getMethodAccessor();
|
||||||
|
if (acc == null)
|
||||||
|
{
|
||||||
|
acc = reflectionFactory.newMethodAccessor(method);
|
||||||
|
method.setMethodAccessor(acc);
|
||||||
|
}
|
||||||
|
object val = acc.invoke(obj, args, ikvm.@internal.CallerID.create(callerID));
|
||||||
|
if (this.ReturnType.IsPrimitive && this.ReturnType != PrimitiveTypeWrapper.VOID)
|
||||||
|
{
|
||||||
|
val = JVM.Unbox(val);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private object[] UnboxArgs(object[] args)
|
||||||
|
{
|
||||||
|
TypeWrapper[] paramTypes = GetParameters();
|
||||||
|
for (int i = 0; i < paramTypes.Length; i++)
|
||||||
|
{
|
||||||
|
if (paramTypes[i].IsPrimitive)
|
||||||
|
{
|
||||||
|
args[i] = JVM.Unbox(args[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
}
|
||||||
#endif // !STATIC_COMPILER
|
#endif // !STATIC_COMPILER
|
||||||
|
|
||||||
#if !STATIC_COMPILER && !FIRST_PASS
|
#if !STATIC_COMPILER && !FIRST_PASS
|
||||||
|
@ -1183,6 +1298,7 @@ namespace IKVM.Internal
|
||||||
#if !STATIC_COMPILER && !FIRST_PASS
|
#if !STATIC_COMPILER && !FIRST_PASS
|
||||||
private static readonly FieldInfo slotField = typeof(java.lang.reflect.Field).GetField("slot", BindingFlags.Instance | BindingFlags.NonPublic);
|
private static readonly FieldInfo slotField = typeof(java.lang.reflect.Field).GetField("slot", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
private volatile object reflectionField;
|
private volatile object reflectionField;
|
||||||
|
private sun.reflect.FieldAccessor jniAccessor;
|
||||||
#endif
|
#endif
|
||||||
internal static readonly FieldWrapper[] EmptyArray = new FieldWrapper[0];
|
internal static readonly FieldWrapper[] EmptyArray = new FieldWrapper[0];
|
||||||
private FieldInfo field;
|
private FieldInfo field;
|
||||||
|
@ -1414,6 +1530,19 @@ namespace IKVM.Internal
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal object GetFieldAccessorJNI()
|
||||||
|
{
|
||||||
|
#if FIRST_PASS
|
||||||
|
return null;
|
||||||
|
#else
|
||||||
|
if (jniAccessor == null)
|
||||||
|
{
|
||||||
|
jniAccessor = reflectionFactory.newFieldAccessor((java.lang.reflect.Field)ToField(false), true);
|
||||||
|
}
|
||||||
|
return jniAccessor;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
#endif // !STATIC_COMPILER
|
#endif // !STATIC_COMPILER
|
||||||
|
|
||||||
internal virtual object GetValue(object obj)
|
internal virtual object GetValue(object obj)
|
||||||
|
|
|
@ -11315,7 +11315,13 @@ namespace IKVM.Internal
|
||||||
|
|
||||||
protected override void EmitSetImpl(CodeEmitter ilgen)
|
protected override void EmitSetImpl(CodeEmitter ilgen)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException();
|
// NOTE even though the field is final, JNI reflection can still be used to set its value!
|
||||||
|
LocalBuilder temp = ilgen.AllocTempLocal(underlyingType);
|
||||||
|
ilgen.Emit(OpCodes.Stloc, temp);
|
||||||
|
ilgen.Emit(OpCodes.Unbox, underlyingType);
|
||||||
|
ilgen.Emit(OpCodes.Ldloc, temp);
|
||||||
|
ilgen.Emit(OpCodes.Stobj, underlyingType);
|
||||||
|
ilgen.ReleaseTempLocal(temp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -5859,7 +5859,7 @@ namespace IKVM.NativeCode.sun.reflect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class FastMethodAccessorImpl : srMethodAccessor
|
internal sealed class FastMethodAccessorImpl : srMethodAccessor
|
||||||
{
|
{
|
||||||
private static readonly MethodInfo valueOfByte;
|
private static readonly MethodInfo valueOfByte;
|
||||||
private static readonly MethodInfo valueOfBoolean;
|
private static readonly MethodInfo valueOfBoolean;
|
||||||
|
@ -5927,7 +5927,7 @@ namespace IKVM.NativeCode.sun.reflect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal FastMethodAccessorImpl(jlrMethod method)
|
internal FastMethodAccessorImpl(jlrMethod method, bool nonvirtual)
|
||||||
{
|
{
|
||||||
MethodWrapper mw = MethodWrapper.FromMethodOrConstructor(method);
|
MethodWrapper mw = MethodWrapper.FromMethodOrConstructor(method);
|
||||||
mw.DeclaringType.Finish();
|
mw.DeclaringType.Finish();
|
||||||
|
@ -6018,7 +6018,7 @@ namespace IKVM.NativeCode.sun.reflect
|
||||||
{
|
{
|
||||||
ilgen.Emit(OpCodes.Ldarg_2);
|
ilgen.Emit(OpCodes.Ldarg_2);
|
||||||
}
|
}
|
||||||
if (mw.IsStatic)
|
if (mw.IsStatic || nonvirtual)
|
||||||
{
|
{
|
||||||
mw.EmitCall(ilgen);
|
mw.EmitCall(ilgen);
|
||||||
}
|
}
|
||||||
|
@ -7672,7 +7672,7 @@ namespace IKVM.NativeCode.sun.reflect
|
||||||
TypeWrapper tw = TypeWrapper.FromClass(m.getDeclaringClass());
|
TypeWrapper tw = TypeWrapper.FromClass(m.getDeclaringClass());
|
||||||
if (!mw.IsDynamicOnly && !tw.IsRemapped)
|
if (!mw.IsDynamicOnly && !tw.IsRemapped)
|
||||||
{
|
{
|
||||||
return new FastMethodAccessorImpl(m);
|
return new FastMethodAccessorImpl(m, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new MethodAccessorImpl(m);
|
return new MethodAccessorImpl(m);
|
||||||
|
|
|
@ -379,6 +379,19 @@ namespace IKVM.Internal
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
#if !STATIC_COMPILER
|
||||||
// helper for JNI (which doesn't have access to core library internals)
|
// helper for JNI (which doesn't have access to core library internals)
|
||||||
internal static object NewDirectByteBuffer(long address, int capacity)
|
internal static object NewDirectByteBuffer(long address, int capacity)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче