Enable ldc <MethodType> to work for unloadable types in dynamic mode.

This commit is contained in:
jfrijters 2013-01-29 16:43:52 +00:00
Родитель ead034f0f5
Коммит ec831d3bc1
2 изменённых файлов: 52 добавлений и 21 удалений

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

@ -2963,8 +2963,21 @@ 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));
break;
case ClassFile.ConstantType.MethodHandle:
context.GetValue<MethodHandleConstant>(constant).Emit(this, ilgen, constant);
break;
case ClassFile.ConstantType.MethodType:
EmitLoadMethodType(ilgen, classFile.GetConstantPoolConstantMethodType(constant));
break;
default:
throw new InvalidOperationException();
}
}
private void EmitLoadClass(CodeEmitter ilgen, TypeWrapper tw)
{ {
TypeWrapper tw = classFile.GetConstantPoolClassType(constant);
if (tw.IsUnloadable) if (tw.IsUnloadable)
{ {
Profiler.Count("EmitDynamicClassLiteral"); Profiler.Count("EmitDynamicClassLiteral");
@ -2977,20 +2990,38 @@ sealed class Compiler
{ {
tw.EmitClassLiteral(ilgen); tw.EmitClassLiteral(ilgen);
} }
break;
} }
case ClassFile.ConstantType.MethodHandle:
context.GetValue<MethodHandleConstant>(constant).Emit(this, ilgen, constant); private void EmitLoadMethodType(CodeEmitter ilgen, ClassFile.ConstantPoolItemMethodType cpi)
break; {
case ClassFile.ConstantType.MethodType: 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
{ {
ClassFile.ConstantPoolItemMethodType cpi = classFile.GetConstantPoolConstantMethodType(constant);
Type delegateType = MethodHandleUtil.CreateDelegateTypeForLoadConstant(cpi.GetArgTypes(), cpi.GetRetType()); Type delegateType = MethodHandleUtil.CreateDelegateTypeForLoadConstant(cpi.GetArgTypes(), cpi.GetRetType());
ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.LoadMethodType.MakeGenericMethod(delegateType)); ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.LoadMethodType.MakeGenericMethod(delegateType));
break;
}
default:
throw new InvalidOperationException();
} }
} }

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

@ -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;