зеркало из 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));
|
ilgen.Emit(OpCodes.Ldstr, classFile.GetConstantPoolConstantString(constant));
|
||||||
break;
|
break;
|
||||||
case ClassFile.ConstantType.Class:
|
case ClassFile.ConstantType.Class:
|
||||||
{
|
EmitLoadClass(ilgen, classFile.GetConstantPoolClassType(constant));
|
||||||
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);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case ClassFile.ConstantType.MethodHandle:
|
case ClassFile.ConstantType.MethodHandle:
|
||||||
context.GetValue<MethodHandleConstant>(constant).Emit(this, ilgen, constant);
|
context.GetValue<MethodHandleConstant>(constant).Emit(this, ilgen, constant);
|
||||||
break;
|
break;
|
||||||
case ClassFile.ConstantType.MethodType:
|
case ClassFile.ConstantType.MethodType:
|
||||||
{
|
EmitLoadMethodType(ilgen, classFile.GetConstantPoolConstantMethodType(constant));
|
||||||
ClassFile.ConstantPoolItemMethodType cpi = classFile.GetConstantPoolConstantMethodType(constant);
|
|
||||||
Type delegateType = MethodHandleUtil.CreateDelegateTypeForLoadConstant(cpi.GetArgTypes(), cpi.GetRetType());
|
|
||||||
ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.LoadMethodType.MakeGenericMethod(delegateType));
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
throw new InvalidOperationException();
|
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 class InvokeDynamicBuilder
|
||||||
{
|
{
|
||||||
private static readonly Type typeofOpenIndyCallSite;
|
private static readonly Type typeofOpenIndyCallSite;
|
||||||
|
|
|
@ -2574,7 +2574,6 @@ sealed class MethodAnalyzer
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
case ClassFile.ConstantType.MethodType:
|
case ClassFile.ConstantType.MethodType:
|
||||||
{
|
{
|
||||||
ClassFile.ConstantPoolItemMethodType cpi = classFile.GetConstantPoolConstantMethodType(instructions[i].Arg1);
|
ClassFile.ConstantPoolItemMethodType cpi = classFile.GetConstantPoolConstantMethodType(instructions[i].Arg1);
|
||||||
|
@ -2590,6 +2589,7 @@ sealed class MethodAnalyzer
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
case ClassFile.ConstantType.MethodHandle:
|
case ClassFile.ConstantType.MethodHandle:
|
||||||
PatchLdcMethodHandle(ref instructions[i]);
|
PatchLdcMethodHandle(ref instructions[i]);
|
||||||
break;
|
break;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче