internal object InvokeJNI(object obj, object[] args, bool nonVirtual, object callerID)
{
#if FIRST_PASS
return null;
#else
#if NOEMIT
java.lang.reflect.Method method = (java.lang.reflect.Method)ToMethodOrConstructor(false);
sun.reflect.MethodAccessor acc = method.getMethodAccessor();
if (acc == null)
{
acc = (sun.reflect.MethodAccessor)IKVM.NativeCode.sun.reflect.ReflectionFactory.newMethodAccessor(null, method);
method.setMethodAccessor(acc);
}
object val = acc.invoke(obj, args, ([email protected])callerID);
if (this.ReturnType.IsPrimitive && this.ReturnType != PrimitiveTypeWrapper.VOID)
{
val = JVM.Unbox(val);
}
return val;
#else
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 = (sun.reflect.ConstructorAccessor)IKVM.NativeCode.sun.reflect.ReflectionFactory.newConstructorAccessor0(null, 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
{
ResolveMethod();
InvokeArgsProcessor proc = new InvokeArgsProcessor(this, method, obj, UnboxArgs(args), ([email protected])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 && !this.DeclaringType.TypeAsBaseType.IsInstanceOfType(obj))
{
ResolveMethod();
return InvokeNonvirtualRemapped(obj, UnboxArgs(args));
}
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, ([email protected])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 = (sun.reflect.MethodAccessor)IKVM.NativeCode.sun.reflect.ReflectionFactory.newMethodAccessor(null, method);
method.setMethodAccessor(acc);
}
object val = acc.invoke(obj, args, ([email protected])callerID);
if (this.ReturnType.IsPrimitive && this.ReturnType != PrimitiveTypeWrapper.VOID)
{
val = JVM.Unbox(val);
}
return val;
}
#endif
#endif
}