зеркало из https://github.com/mono/ikvm-fork.git
Enable ldc <MethodType> to work for unloadable types in dynamic mode.
This commit is contained in:
Родитель
ead034f0f5
Коммит
ec831d3bc1
|
@ -2963,37 +2963,68 @@ sealed class Compiler
|
|||
ilgen.Emit(OpCodes.Ldstr, classFile.GetConstantPoolConstantString(constant));
|
||||
break;
|
||||
case ClassFile.ConstantType.Class:
|
||||
{
|
||||
TypeWrapper tw = classFile.GetConstantPoolClassType(constant);
|
||||
if (tw.IsUnloadable)
|
||||
{
|
||||
Profiler.Count("EmitDynamicClassLiteral");
|
||||
ilgen.Emit(OpCodes.Ldtoken, clazz.TypeAsTBD);
|
||||
ilgen.Emit(OpCodes.Ldstr, tw.Name);
|
||||
ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.DynamicClassLiteral);
|
||||
java_lang_Class.EmitCheckcast(clazz, ilgen);
|
||||
}
|
||||
else
|
||||
{
|
||||
tw.EmitClassLiteral(ilgen);
|
||||
}
|
||||
EmitLoadClass(ilgen, classFile.GetConstantPoolClassType(constant));
|
||||
break;
|
||||
}
|
||||
case ClassFile.ConstantType.MethodHandle:
|
||||
context.GetValue<MethodHandleConstant>(constant).Emit(this, ilgen, constant);
|
||||
break;
|
||||
case ClassFile.ConstantType.MethodType:
|
||||
{
|
||||
ClassFile.ConstantPoolItemMethodType cpi = classFile.GetConstantPoolConstantMethodType(constant);
|
||||
Type delegateType = MethodHandleUtil.CreateDelegateTypeForLoadConstant(cpi.GetArgTypes(), cpi.GetRetType());
|
||||
ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.LoadMethodType.MakeGenericMethod(delegateType));
|
||||
EmitLoadMethodType(ilgen, classFile.GetConstantPoolConstantMethodType(constant));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private void EmitLoadClass(CodeEmitter ilgen, TypeWrapper tw)
|
||||
{
|
||||
if (tw.IsUnloadable)
|
||||
{
|
||||
Profiler.Count("EmitDynamicClassLiteral");
|
||||
ilgen.Emit(OpCodes.Ldtoken, clazz.TypeAsTBD);
|
||||
ilgen.Emit(OpCodes.Ldstr, tw.Name);
|
||||
ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.DynamicClassLiteral);
|
||||
java_lang_Class.EmitCheckcast(clazz, ilgen);
|
||||
}
|
||||
else
|
||||
{
|
||||
tw.EmitClassLiteral(ilgen);
|
||||
}
|
||||
}
|
||||
|
||||
private void EmitLoadMethodType(CodeEmitter ilgen, ClassFile.ConstantPoolItemMethodType cpi)
|
||||
{
|
||||
TypeWrapper ret = cpi.GetRetType();
|
||||
TypeWrapper[] args = cpi.GetArgTypes();
|
||||
TypeWrapper tw = ret;
|
||||
for (int i = 0; !tw.IsUnloadable && i < args.Length; i++)
|
||||
{
|
||||
tw = args[i];
|
||||
}
|
||||
if (tw.IsUnloadable)
|
||||
{
|
||||
EmitLoadClass(ilgen, ret);
|
||||
ilgen.EmitLdc_I4(args.Length);
|
||||
ilgen.Emit(OpCodes.Newarr, CoreClasses.java.lang.Class.Wrapper.TypeAsArrayType);
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Dup);
|
||||
ilgen.EmitLdc_I4(i);
|
||||
EmitLoadClass(ilgen, args[i]);
|
||||
ilgen.Emit(OpCodes.Stelem_Ref);
|
||||
}
|
||||
MethodWrapper methodType = ClassLoaderWrapper.LoadClassCritical("java.lang.invoke.MethodType")
|
||||
.GetMethodWrapper("methodType", "(Ljava.lang.Class;[Ljava.lang.Class;)Ljava.lang.invoke.MethodType;", false);
|
||||
methodType.Link();
|
||||
methodType.EmitCall(ilgen);
|
||||
}
|
||||
else
|
||||
{
|
||||
Type delegateType = MethodHandleUtil.CreateDelegateTypeForLoadConstant(cpi.GetArgTypes(), cpi.GetRetType());
|
||||
ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.LoadMethodType.MakeGenericMethod(delegateType));
|
||||
}
|
||||
}
|
||||
|
||||
private static class InvokeDynamicBuilder
|
||||
{
|
||||
private static readonly Type typeofOpenIndyCallSite;
|
||||
|
|
|
@ -2574,7 +2574,6 @@ sealed class MethodAnalyzer
|
|||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case ClassFile.ConstantType.MethodType:
|
||||
{
|
||||
ClassFile.ConstantPoolItemMethodType cpi = classFile.GetConstantPoolConstantMethodType(instructions[i].Arg1);
|
||||
|
@ -2590,6 +2589,7 @@ sealed class MethodAnalyzer
|
|||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case ClassFile.ConstantType.MethodHandle:
|
||||
PatchLdcMethodHandle(ref instructions[i]);
|
||||
break;
|
||||
|
|
Загрузка…
Ссылка в новой задаче