Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/ikvm-fork.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjfrijters <jfrijters>2014-07-08 12:44:08 +0400
committerjfrijters <jfrijters>2014-07-08 12:44:08 +0400
commit77cfa0d12a2811ec6dde829edafaac46e3bbb615 (patch)
tree3b5af106e6b6bf8ba98d5eb9d015f7a65ef04447
parent1cd5828b82a0998a92579757582c0ce321c317df (diff)
Use the same nested type for lambdas that are created with an invokedynamic to the same constant pool item (so that deserialization uses the same class as the original).
-rw-r--r--runtime/LambdaMetafactory.cs19
-rw-r--r--runtime/compiler.cs12
2 files changed, 16 insertions, 15 deletions
diff --git a/runtime/LambdaMetafactory.cs b/runtime/LambdaMetafactory.cs
index c987f33d..afec4e13 100644
--- a/runtime/LambdaMetafactory.cs
+++ b/runtime/LambdaMetafactory.cs
@@ -35,16 +35,19 @@ using System.Reflection.Emit;
namespace IKVM.Internal
{
- static class LambdaMetafactory
+ sealed class LambdaMetafactory
{
- internal static bool Emit(DynamicTypeWrapper.FinishContext context, ClassFile classFile, ClassFile.ConstantPoolItemInvokeDynamic cpi, CodeEmitter ilgen)
+ private MethodBuilder ctor;
+
+ internal static bool Emit(DynamicTypeWrapper.FinishContext context, ClassFile classFile, int constantPoolIndex, ClassFile.ConstantPoolItemInvokeDynamic cpi, CodeEmitter ilgen)
{
ClassFile.BootstrapMethod bsm = classFile.GetBootstrapMethod(cpi.BootstrapMethod);
if (!IsLambdaMetafactory(classFile, bsm) && !IsLambdaAltMetafactory(classFile, bsm))
{
return false;
}
- if (!EmitImpl(context, classFile, cpi, bsm, ilgen))
+ LambdaMetafactory lmf = context.GetValue<LambdaMetafactory>(constantPoolIndex);
+ if (lmf.ctor == null && !lmf.EmitImpl(context, classFile, cpi, bsm, ilgen))
{
#if STATIC_COMPILER
if (context.TypeWrapper.GetClassLoader().DisableDynamicBinding)
@@ -54,10 +57,13 @@ namespace IKVM.Internal
#endif
return false;
}
+ ilgen.Emit(OpCodes.Newobj, lmf.ctor);
+ // the CLR verification rules about type merging mean we have to explicitly cast to the interface type here
+ ilgen.Emit(OpCodes.Castclass, cpi.GetRetType().TypeAsBaseType);
return true;
}
- private static bool EmitImpl(DynamicTypeWrapper.FinishContext context, ClassFile classFile, ClassFile.ConstantPoolItemInvokeDynamic cpi, ClassFile.BootstrapMethod bsm, CodeEmitter ilgen)
+ private bool EmitImpl(DynamicTypeWrapper.FinishContext context, ClassFile classFile, ClassFile.ConstantPoolItemInvokeDynamic cpi, ClassFile.BootstrapMethod bsm, CodeEmitter ilgen)
{
if (HasUnloadable(cpi))
{
@@ -178,11 +184,8 @@ namespace IKVM.Internal
{
tb.AddInterfaceImplementation(CoreClasses.java.io.Serializable.Wrapper.TypeAsBaseType);
}
- MethodBuilder ctor = CreateConstructorAndDispatch(context, cpi.GetArgTypes(), tb, interfaceMethod, implParameters, samMethodType, implMethod, instantiatedMethodType, serializable);
+ ctor = CreateConstructorAndDispatch(context, cpi.GetArgTypes(), tb, interfaceMethod, implParameters, samMethodType, implMethod, instantiatedMethodType, serializable);
AddDefaultInterfaceMethods(context, methodList, tb);
- ilgen.Emit(OpCodes.Newobj, ctor);
- // the CLR verification rules about type merging mean we have to explicitly cast to the interface type here
- ilgen.Emit(OpCodes.Castclass, interfaceType.TypeAsBaseType);
return true;
}
diff --git a/runtime/compiler.cs b/runtime/compiler.cs
index fc1f264a..e38729f8 100644
--- a/runtime/compiler.cs
+++ b/runtime/compiler.cs
@@ -1434,8 +1434,11 @@ sealed class Compiler
{
ClassFile.ConstantPoolItemInvokeDynamic cpi = classFile.GetInvokeDynamic(instr.Arg1);
CastInterfaceArgs(null, cpi.GetArgTypes(), i, false);
- EmitInvokeDynamic(cpi);
- EmitReturnTypeConversion(cpi.GetRetType());
+ if (!LambdaMetafactory.Emit(context, classFile, instr.Arg1, cpi, ilGenerator))
+ {
+ EmitInvokeDynamic(cpi);
+ EmitReturnTypeConversion(cpi.GetRetType());
+ }
nonleaf = true;
break;
}
@@ -3208,11 +3211,6 @@ sealed class Compiler
private void EmitInvokeDynamic(ClassFile.ConstantPoolItemInvokeDynamic cpi)
{
- if (LambdaMetafactory.Emit(context, classFile, cpi, ilGenerator))
- {
- // we intrinsified the lambda factory
- return;
- }
CodeEmitter ilgen = ilGenerator;
TypeWrapper[] args = cpi.GetArgTypes();
CodeEmitterLocal[] temps = new CodeEmitterLocal[args.Length];