Added support for DirectMethodHandle to ghost and value types.

This commit is contained in:
jfrijters 2011-08-09 07:39:03 +00:00
Родитель 961928341e
Коммит 24c38baf9a
1 изменённых файлов: 15 добавлений и 2 удалений

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

@ -284,6 +284,11 @@ static partial class MethodHandleUtil
ilgen.Emit(opc, val); ilgen.Emit(opc, val);
} }
internal void LoadFirstArgAddress()
{
ilgen.Emit(OpCodes.Ldarga, (short)firstArg);
}
internal void Ldarg(int i) internal void Ldarg(int i)
{ {
i += firstArg; i += firstArg;
@ -1044,6 +1049,7 @@ static class Java_java_lang_invoke_MethodHandleNatives
if (mi != null if (mi != null
&& !tw.IsRemapped && !tw.IsRemapped
&& !tw.IsGhost && !tw.IsGhost
&& !tw.IsNonPrimitiveValueType
&& self.type().parameterCount() <= MethodHandleUtil.MaxArity && self.type().parameterCount() <= MethodHandleUtil.MaxArity
// FXBUG we should be able to use a normal (unbound) delegate for virtual methods // FXBUG we should be able to use a normal (unbound) delegate for virtual methods
// (when doDispatch is set), but the x64 CLR crashes when doing a virtual method dispatch on // (when doDispatch is set), but the x64 CLR crashes when doing a virtual method dispatch on
@ -1055,16 +1061,23 @@ static class Java_java_lang_invoke_MethodHandleNatives
} }
else else
{ {
if (tw.IsGhost || mw.Name == StringConstants.INIT) if (mw.Name == StringConstants.INIT)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
// slow path where we emit a DynamicMethod // slow path where we emit a DynamicMethod
MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder("DirectMethodHandle:" + mw.Name, self.type()); MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder("DirectMethodHandle:" + mw.Name, self.type());
for (int i = 0, count = self.type().parameterCount(); i < count; i++) for (int i = 0, count = self.type().parameterCount(); i < count; i++)
{
if (i == 0 && !mw.IsStatic && (tw.IsGhost || tw.IsNonPrimitiveValueType))
{
dm.LoadFirstArgAddress();
}
else
{ {
dm.Ldarg(i); dm.Ldarg(i);
} }
}
if (doDispatch && !mw.IsStatic) if (doDispatch && !mw.IsStatic)
{ {
dm.Callvirt(mw); dm.Callvirt(mw);