コード例 #1
0
 private static bool CheckConstraints(ClassFile.ConstantPoolItemMethodType instantiatedMethodType, ClassFile.ConstantPoolItemMethodType methodType, TypeWrapper[] args, TypeWrapper[] implParameters)
 {
     if (!IsSubTypeOf(instantiatedMethodType, methodType))
     {
         Fail("instantiatedMethodType <= methodType");
         return(false);
     }
     if (args.Length + methodType.GetArgTypes().Length != implParameters.Length)
     {
         Fail("K + N = M");
         return(false);
     }
     for (int i = 0, K = args.Length; i < K; i++)
     {
         if (args[i] == implParameters[i])
         {
             // ok
         }
         else if (args[i].IsPrimitive || implParameters[i].IsPrimitive || !args[i].IsSubTypeOf(implParameters[i]))
         {
             Fail("For i=1..K, Di = Ai");
             return(false);
         }
     }
     for (int i = 0, N = methodType.GetArgTypes().Length, k = args.Length; i < N; i++)
     {
         if (!IsAdaptable(instantiatedMethodType.GetArgTypes()[i], implParameters[i + k], false))
         {
             Fail("For i=1..N, Ti is adaptable to Aj, where j=i+k");
             return(false);
         }
     }
     return(true);
 }
コード例 #2
0
        private static bool IsSubTypeOf(ClassFile.ConstantPoolItemMethodType instantiatedMethodType, ClassFile.ConstantPoolItemMethodType samMethodType)
        {
            TypeWrapper[] T = instantiatedMethodType.GetArgTypes();
            TypeWrapper[] U = samMethodType.GetArgTypes();
            if (T.Length != U.Length)
            {
                return(false);
            }
            for (int i = 0; i < T.Length; i++)
            {
                if (!T[i].IsAssignableTo(U[i]))
                {
                    return(false);
                }
            }
            TypeWrapper Rt = instantiatedMethodType.GetRetType();
            TypeWrapper Ru = samMethodType.GetRetType();

            return(Rt.IsAssignableTo(Ru));
        }
コード例 #3
0
 private static bool MatchSignatures(MethodWrapper interfaceMethod, ClassFile.ConstantPoolItemMethodType samMethodType)
 {
     return(interfaceMethod.ReturnType == samMethodType.GetRetType() &&
            MatchTypes(interfaceMethod.GetParameters(), samMethodType.GetArgTypes()));
 }
コード例 #4
0
        private static bool IsSupportedImplMethod(ClassFile.ConstantPoolItemMethodHandle implMethod, TypeWrapper caller, TypeWrapper[] captured, ClassFile.ConstantPoolItemMethodType instantiatedMethodType)
        {
            switch (implMethod.Kind)
            {
            case ClassFile.RefKind.invokeVirtual:
            case ClassFile.RefKind.invokeInterface:
            case ClassFile.RefKind.newInvokeSpecial:
            case ClassFile.RefKind.invokeStatic:
            case ClassFile.RefKind.invokeSpecial:
                break;

            default:
                return(false);
            }
            MethodWrapper mw = (MethodWrapper)implMethod.Member;

            if (mw == null || mw.HasCallerID || DynamicTypeWrapper.RequiresDynamicReflectionCallerClass(mw.DeclaringType.Name, mw.Name, mw.Signature))
            {
                return(false);
            }
            TypeWrapper instance;

            if (mw.IsConstructor)
            {
                instance = mw.DeclaringType;
            }
            else if (mw.IsStatic)
            {
                instance = null;
            }
            else
            {
                // if implMethod is an instance method, the type of the first captured value must be subtype of implMethod.DeclaringType
                instance = captured.Length == 0 ? instantiatedMethodType.GetArgTypes()[0] : captured[0];
                if (!instance.IsAssignableTo(mw.DeclaringType))
                {
                    return(false);
                }
            }
            if (!mw.IsAccessibleFrom(mw.DeclaringType, caller, instance))
            {
                return(false);
            }
            mw.Link();
            return(true);
        }
コード例 #5
0
        private bool EmitImpl(DynamicTypeWrapper.FinishContext context, ClassFile classFile, ClassFile.ConstantPoolItemInvokeDynamic cpi, ClassFile.BootstrapMethod bsm, CodeEmitter ilgen)
        {
            if (HasUnloadable(cpi))
            {
                Fail("cpi has unloadable");
                return(false);
            }
            bool serializable = false;

            TypeWrapper[] markers = TypeWrapper.EmptyArray;
            ClassFile.ConstantPoolItemMethodType[] bridges = null;
            if (bsm.ArgumentCount > 3)
            {
                AltFlags flags = (AltFlags)classFile.GetConstantPoolConstantInteger(bsm.GetArgument(3));
                serializable = (flags & AltFlags.Serializable) != 0;
                int argpos = 4;
                if ((flags & AltFlags.Markers) != 0)
                {
                    markers = new TypeWrapper[classFile.GetConstantPoolConstantInteger(bsm.GetArgument(argpos++))];
                    for (int i = 0; i < markers.Length; i++)
                    {
                        if ((markers[i] = classFile.GetConstantPoolClassType(bsm.GetArgument(argpos++))).IsUnloadable)
                        {
                            Fail("unloadable marker");
                            return(false);
                        }
                    }
                }
                if ((flags & AltFlags.Bridges) != 0)
                {
                    bridges = new ClassFile.ConstantPoolItemMethodType[classFile.GetConstantPoolConstantInteger(bsm.GetArgument(argpos++))];
                    for (int i = 0; i < bridges.Length; i++)
                    {
                        bridges[i] = classFile.GetConstantPoolConstantMethodType(bsm.GetArgument(argpos++));
                        if (HasUnloadable(bridges[i]))
                        {
                            Fail("unloadable bridge");
                            return(false);
                        }
                    }
                }
            }
            ClassFile.ConstantPoolItemMethodType   samMethodType          = classFile.GetConstantPoolConstantMethodType(bsm.GetArgument(0));
            ClassFile.ConstantPoolItemMethodHandle implMethod             = classFile.GetConstantPoolConstantMethodHandle(bsm.GetArgument(1));
            ClassFile.ConstantPoolItemMethodType   instantiatedMethodType = classFile.GetConstantPoolConstantMethodType(bsm.GetArgument(2));
            if (HasUnloadable(samMethodType) ||
                HasUnloadable((ClassFile.ConstantPoolItemMI)implMethod.MemberConstantPoolItem) ||
                HasUnloadable(instantiatedMethodType))
            {
                Fail("bsm args has unloadable");
                return(false);
            }
            TypeWrapper interfaceType = cpi.GetRetType();

            MethodWrapper[] methodList;
            if (!CheckSupportedInterfaces(context.TypeWrapper, interfaceType, markers, bridges, out methodList))
            {
                Fail("unsupported interface");
                return(false);
            }
            if (serializable && Array.Exists(methodList, delegate(MethodWrapper mw) { return(mw.Name == "writeReplace" && mw.Signature == "()Ljava.lang.Object;"); }))
            {
                Fail("writeReplace");
                return(false);
            }
            if (!IsSupportedImplMethod(implMethod, context.TypeWrapper, cpi.GetArgTypes(), instantiatedMethodType))
            {
                Fail("implMethod " + implMethod.MemberConstantPoolItem.Class + "::" + implMethod.MemberConstantPoolItem.Name + implMethod.MemberConstantPoolItem.Signature);
                return(false);
            }
            TypeWrapper[] implParameters = GetImplParameters(implMethod);
            CheckConstraints(instantiatedMethodType, samMethodType, cpi.GetArgTypes(), implParameters);
            if (bridges != null)
            {
                foreach (ClassFile.ConstantPoolItemMethodType bridge in bridges)
                {
                    if (bridge.Signature == samMethodType.Signature)
                    {
                        Fail("bridge signature matches sam");
                        return(false);
                    }
                    if (!CheckConstraints(instantiatedMethodType, bridge, cpi.GetArgTypes(), implParameters))
                    {
                        Fail("bridge constraints");
                        return(false);
                    }
                }
            }
            if (instantiatedMethodType.GetRetType() != PrimitiveTypeWrapper.VOID)
            {
                TypeWrapper Rt = instantiatedMethodType.GetRetType();
                TypeWrapper Ra = GetImplReturnType(implMethod);
                if (Ra == PrimitiveTypeWrapper.VOID || !IsAdaptable(Ra, Rt, true))
                {
                    Fail("The return type Rt is void, or the return type Ra is not void and is adaptable to Rt");
                    return(false);
                }
            }
            MethodWrapper        interfaceMethod = null;
            List <MethodWrapper> methods         = new List <MethodWrapper>();

            foreach (MethodWrapper mw in methodList)
            {
                if (mw.Name == cpi.Name && mw.Signature == samMethodType.Signature)
                {
                    interfaceMethod = mw;
                    methods.Add(mw);
                }
                else if (mw.IsAbstract && !IsObjectMethod(mw))
                {
                    methods.Add(mw);
                }
            }
            if (interfaceMethod == null || !interfaceMethod.IsAbstract || IsObjectMethod(interfaceMethod) || !MatchSignatures(interfaceMethod, samMethodType))
            {
                Fail("interfaceMethod");
                return(false);
            }

            TypeBuilder tb = context.DefineAnonymousClass();

            // we're not implementing the interfaces recursively (because we don't care about .NET Compact anymore),
            // but should we decide to do that, we'd need to somehow communicate to AnonymousTypeWrapper what the 'real' interface is
            tb.AddInterfaceImplementation(interfaceType.TypeAsBaseType);
            if (serializable && Array.IndexOf(markers, CoreClasses.java.io.Serializable.Wrapper) == -1)
            {
                tb.AddInterfaceImplementation(CoreClasses.java.io.Serializable.Wrapper.TypeAsBaseType);
            }
            foreach (TypeWrapper marker in markers)
            {
                tb.AddInterfaceImplementation(marker.TypeAsBaseType);
            }
            ctor = CreateConstructorAndDispatch(context, cpi, tb, methods, implParameters, samMethodType, implMethod, instantiatedMethodType, serializable);
            AddDefaultInterfaceMethods(context, methodList, tb);
            return(true);
        }
コード例 #6
0
        private static void EmitDispatch(DynamicTypeWrapper.FinishContext context, TypeWrapper[] args, TypeBuilder tb, MethodWrapper interfaceMethod, TypeWrapper[] implParameters,
                                         ClassFile.ConstantPoolItemMethodHandle implMethod, ClassFile.ConstantPoolItemMethodType instantiatedMethodType, FieldBuilder[] capturedFields)
        {
            MethodBuilder mb = interfaceMethod.GetDefineMethodHelper().DefineMethod(context.TypeWrapper, tb, interfaceMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final);

            if (interfaceMethod.Name != interfaceMethod.RealName)
            {
                tb.DefineMethodOverride(mb, (MethodInfo)interfaceMethod.GetMethod());
            }
            CodeEmitter ilgen = CodeEmitter.Create(mb);

            for (int i = 0; i < capturedFields.Length; i++)
            {
                ilgen.EmitLdarg(0);
                OpCode opc = OpCodes.Ldfld;
                if (i == 0 && args[0].IsGhost)
                {
                    switch (implMethod.Kind)
                    {
                    case ClassFile.RefKind.invokeInterface:
                    case ClassFile.RefKind.invokeVirtual:
                    case ClassFile.RefKind.invokeSpecial:
                        opc = OpCodes.Ldflda;
                        break;
                    }
                }
                ilgen.Emit(opc, capturedFields[i]);
            }
            for (int i = 0, count = interfaceMethod.GetParameters().Length, k = capturedFields.Length; i < count; i++)
            {
                ilgen.EmitLdarg(i + 1);
                TypeWrapper Ui = interfaceMethod.GetParameters()[i];
                TypeWrapper Ti = instantiatedMethodType.GetArgTypes()[i];
                TypeWrapper Aj = implParameters[i + k];
                if (Ui == PrimitiveTypeWrapper.BYTE)
                {
                    ilgen.Emit(OpCodes.Conv_I1);
                }
                if (Ti != Ui)
                {
                    if (Ti.IsGhost)
                    {
                        Ti.EmitConvStackTypeToSignatureType(ilgen, Ui);
                    }
                    else if (Ui.IsGhost)
                    {
                        Ui.EmitConvSignatureTypeToStackType(ilgen);
                    }
                    else
                    {
                        Ti.EmitCheckcast(ilgen);
                    }
                }
                if (Ti != Aj)
                {
                    if (Ti.IsPrimitive && !Aj.IsPrimitive)
                    {
                        Boxer.EmitBox(ilgen, Ti);
                    }
                    else if (!Ti.IsPrimitive && Aj.IsPrimitive)
                    {
                        TypeWrapper primitive = GetPrimitiveFromWrapper(Ti);
                        Boxer.EmitUnbox(ilgen, primitive, false);
                        if (primitive == PrimitiveTypeWrapper.BYTE)
                        {
                            ilgen.Emit(OpCodes.Conv_I1);
                        }
                    }
                    else if (Aj == PrimitiveTypeWrapper.LONG)
                    {
                        ilgen.Emit(OpCodes.Conv_I8);
                    }
                    else if (Aj == PrimitiveTypeWrapper.FLOAT)
                    {
                        ilgen.Emit(OpCodes.Conv_R4);
                    }
                    else if (Aj == PrimitiveTypeWrapper.DOUBLE)
                    {
                        ilgen.Emit(OpCodes.Conv_R8);
                    }
                }
            }
            switch (implMethod.Kind)
            {
            case ClassFile.RefKind.invokeVirtual:
            case ClassFile.RefKind.invokeInterface:
                ((MethodWrapper)implMethod.Member).EmitCallvirt(ilgen);
                break;

            case ClassFile.RefKind.newInvokeSpecial:
                ((MethodWrapper)implMethod.Member).EmitNewobj(ilgen);
                break;

            case ClassFile.RefKind.invokeStatic:
            case ClassFile.RefKind.invokeSpecial:
                ((MethodWrapper)implMethod.Member).EmitCall(ilgen);
                break;

            default:
                throw new InvalidOperationException();
            }
            TypeWrapper Ru = interfaceMethod.ReturnType;
            TypeWrapper Ra = GetImplReturnType(implMethod);
            TypeWrapper Rt = instantiatedMethodType.GetRetType();

            if (Ra == PrimitiveTypeWrapper.BYTE)
            {
                ilgen.Emit(OpCodes.Conv_I1);
            }
            if (Ra != Ru)
            {
                if (Ru == PrimitiveTypeWrapper.VOID)
                {
                    ilgen.Emit(OpCodes.Pop);
                }
                else if (Ra.IsGhost)
                {
                    Ra.EmitConvSignatureTypeToStackType(ilgen);
                }
                else if (Ru.IsGhost)
                {
                    Ru.EmitConvStackTypeToSignatureType(ilgen, Ra);
                }
            }
            if (Ra != Rt)
            {
                if (Rt.IsPrimitive)
                {
                    if (Rt == PrimitiveTypeWrapper.VOID)
                    {
                        // already popped
                    }
                    else if (!Ra.IsPrimitive)
                    {
                        TypeWrapper primitive = GetPrimitiveFromWrapper(Ra);
                        if (primitive != null)
                        {
                            Boxer.EmitUnbox(ilgen, primitive, false);
                        }
                        else
                        {
                            // If Q is not a primitive wrapper, cast Q to the base Wrapper(S); for example Number for numeric types
                            EmitConvertingUnbox(ilgen, Rt);
                        }
                    }
                    else if (Rt == PrimitiveTypeWrapper.LONG)
                    {
                        ilgen.Emit(OpCodes.Conv_I8);
                    }
                    else if (Rt == PrimitiveTypeWrapper.FLOAT)
                    {
                        ilgen.Emit(OpCodes.Conv_R4);
                    }
                    else if (Rt == PrimitiveTypeWrapper.DOUBLE)
                    {
                        ilgen.Emit(OpCodes.Conv_R8);
                    }
                }
                else if (Ra.IsPrimitive)
                {
                    Boxer.EmitBox(ilgen, GetPrimitiveFromWrapper(Rt));
                }
                else
                {
                    Rt.EmitCheckcast(ilgen);
                }
            }
            ilgen.EmitTailCallPrevention();
            ilgen.Emit(OpCodes.Ret);
            ilgen.DoEmit();
        }
コード例 #7
0
        private static MethodBuilder CreateConstructorAndDispatch(DynamicTypeWrapper.FinishContext context, ClassFile.ConstantPoolItemInvokeDynamic cpi, TypeBuilder tb,
                                                                  List <MethodWrapper> methods, TypeWrapper[] implParameters, ClassFile.ConstantPoolItemMethodType samMethodType, ClassFile.ConstantPoolItemMethodHandle implMethod,
                                                                  ClassFile.ConstantPoolItemMethodType instantiatedMethodType, bool serializable)
        {
            TypeWrapper[] args = cpi.GetArgTypes();

            // captured values
            Type[]         capturedTypes  = new Type[args.Length];
            FieldBuilder[] capturedFields = new FieldBuilder[capturedTypes.Length];
            for (int i = 0; i < capturedTypes.Length; i++)
            {
                capturedTypes[i] = args[i].TypeAsSignatureType;
                FieldAttributes attr = FieldAttributes.Private;
                if (i > 0 || !args[0].IsGhost)
                {
                    attr |= FieldAttributes.InitOnly;
                }
                capturedFields[i] = tb.DefineField("arg$" + (i + 1), capturedTypes[i], attr);
            }

            // constructor
            MethodBuilder ctor  = ReflectUtil.DefineConstructor(tb, MethodAttributes.Assembly, capturedTypes);
            CodeEmitter   ilgen = CodeEmitter.Create(ctor);

            ilgen.Emit(OpCodes.Ldarg_0);
            ilgen.Emit(OpCodes.Call, Types.Object.GetConstructor(Type.EmptyTypes));
            for (int i = 0; i < capturedTypes.Length; i++)
            {
                ilgen.EmitLdarg(0);
                ilgen.EmitLdarg(i + 1);
                ilgen.Emit(OpCodes.Stfld, capturedFields[i]);
            }
            ilgen.Emit(OpCodes.Ret);
            ilgen.DoEmit();

            // dispatch methods
            foreach (MethodWrapper mw in methods)
            {
                EmitDispatch(context, args, tb, mw, implParameters, implMethod, instantiatedMethodType, capturedFields);
            }

            // writeReplace method
            if (serializable)
            {
                MethodBuilder writeReplace = tb.DefineMethod("writeReplace", MethodAttributes.Private, Types.Object, Type.EmptyTypes);
                ilgen = CodeEmitter.Create(writeReplace);
                context.TypeWrapper.EmitClassLiteral(ilgen);
                ilgen.Emit(OpCodes.Ldstr, cpi.GetRetType().Name.Replace('.', '/'));
                ilgen.Emit(OpCodes.Ldstr, cpi.Name);
                ilgen.Emit(OpCodes.Ldstr, samMethodType.Signature.Replace('.', '/'));
                ilgen.EmitLdc_I4((int)implMethod.Kind);
                ilgen.Emit(OpCodes.Ldstr, implMethod.Class.Replace('.', '/'));
                ilgen.Emit(OpCodes.Ldstr, implMethod.Name);
                ilgen.Emit(OpCodes.Ldstr, implMethod.Signature.Replace('.', '/'));
                ilgen.Emit(OpCodes.Ldstr, instantiatedMethodType.Signature.Replace('.', '/'));
                ilgen.EmitLdc_I4(capturedFields.Length);
                ilgen.Emit(OpCodes.Newarr, Types.Object);
                for (int i = 0; i < capturedFields.Length; i++)
                {
                    ilgen.Emit(OpCodes.Dup);
                    ilgen.EmitLdc_I4(i);
                    ilgen.EmitLdarg(0);
                    ilgen.Emit(OpCodes.Ldfld, capturedFields[i]);
                    if (args[i].IsPrimitive)
                    {
                        Boxer.EmitBox(ilgen, args[i]);
                    }
                    else if (args[i].IsGhost)
                    {
                        args[i].EmitConvSignatureTypeToStackType(ilgen);
                    }
                    ilgen.Emit(OpCodes.Stelem, Types.Object);
                }
                MethodWrapper ctorSerializedLambda = ClassLoaderWrapper.LoadClassCritical("java.lang.invoke.SerializedLambda").GetMethodWrapper(StringConstants.INIT,
                                                                                                                                                "(Ljava.lang.Class;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;ILjava.lang.String;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;[Ljava.lang.Object;)V", false);
                ctorSerializedLambda.Link();
                ctorSerializedLambda.EmitNewobj(ilgen);
                ilgen.Emit(OpCodes.Ret);
                ilgen.DoEmit();

                if (!context.TypeWrapper.GetClassLoader().NoAutomagicSerialization)
                {
                    // add .NET serialization interop support
                    Serialization.MarkSerializable(tb);
                    Serialization.AddGetObjectData(tb);
                }
            }

            return(ctor);
        }
コード例 #8
0
 private static bool HasUnloadable(ClassFile.ConstantPoolItemMethodType cpi)
 {
     return(HasUnloadable(cpi.GetArgTypes()) || cpi.GetRetType().IsUnloadable);
 }
コード例 #9
0
		private bool EmitImpl(DynamicTypeWrapper.FinishContext context, ClassFile classFile, ClassFile.ConstantPoolItemInvokeDynamic cpi, ClassFile.BootstrapMethod bsm, CodeEmitter ilgen)
		{
			if (HasUnloadable(cpi))
			{
				Fail("cpi has unloadable");
				return false;
			}
			bool serializable = false;
			TypeWrapper[] markers = TypeWrapper.EmptyArray;
			ClassFile.ConstantPoolItemMethodType[] bridges = null;
			if (bsm.ArgumentCount > 3)
			{
				AltFlags flags = (AltFlags)classFile.GetConstantPoolConstantInteger(bsm.GetArgument(3));
				serializable = (flags & AltFlags.Serializable) != 0;
				int argpos = 4;
				if ((flags & AltFlags.Markers) != 0)
				{
					markers = new TypeWrapper[classFile.GetConstantPoolConstantInteger(bsm.GetArgument(argpos++))];
					for (int i = 0; i < markers.Length; i++)
					{
						if ((markers[i] = classFile.GetConstantPoolClassType(bsm.GetArgument(argpos++))).IsUnloadable)
						{
							Fail("unloadable marker");
							return false;
						}
					}
				}
				if ((flags & AltFlags.Bridges) != 0)
				{
					bridges = new ClassFile.ConstantPoolItemMethodType[classFile.GetConstantPoolConstantInteger(bsm.GetArgument(argpos++))];
					for (int i = 0; i < bridges.Length; i++)
					{
						bridges[i] = classFile.GetConstantPoolConstantMethodType(bsm.GetArgument(argpos++));
						if (HasUnloadable(bridges[i]))
						{
							Fail("unloadable bridge");
							return false;
						}
					}
				}
			}
			ClassFile.ConstantPoolItemMethodType samMethodType = classFile.GetConstantPoolConstantMethodType(bsm.GetArgument(0));
			ClassFile.ConstantPoolItemMethodHandle implMethod = classFile.GetConstantPoolConstantMethodHandle(bsm.GetArgument(1));
			ClassFile.ConstantPoolItemMethodType instantiatedMethodType = classFile.GetConstantPoolConstantMethodType(bsm.GetArgument(2));
			if (HasUnloadable(samMethodType)
				|| HasUnloadable((ClassFile.ConstantPoolItemMI)implMethod.MemberConstantPoolItem)
				|| HasUnloadable(instantiatedMethodType))
			{
				Fail("bsm args has unloadable");
				return false;
			}
			TypeWrapper interfaceType = cpi.GetRetType();
			MethodWrapper[] methodList;
			if (!CheckSupportedInterfaces(context.TypeWrapper, interfaceType, markers, bridges, out methodList))
			{
				Fail("unsupported interface");
				return false;
			}
			if (serializable && Array.Exists(methodList, delegate(MethodWrapper mw) { return mw.Name == "writeReplace" && mw.Signature == "()Ljava.lang.Object;"; }))
			{
				Fail("writeReplace");
				return false;
			}
			if (!IsSupportedImplMethod(implMethod, context.TypeWrapper, cpi.GetArgTypes(), instantiatedMethodType))
			{
				Fail("implMethod " + implMethod.MemberConstantPoolItem.Class + "::" + implMethod.MemberConstantPoolItem.Name + implMethod.MemberConstantPoolItem.Signature);
				return false;
			}
			TypeWrapper[] implParameters = GetImplParameters(implMethod);
			CheckConstraints(instantiatedMethodType, samMethodType, cpi.GetArgTypes(), implParameters);
			if (bridges != null)
			{
				foreach (ClassFile.ConstantPoolItemMethodType bridge in bridges)
				{
					if (bridge.Signature == samMethodType.Signature)
					{
						Fail("bridge signature matches sam");
						return false;
					}
					if (!CheckConstraints(instantiatedMethodType, bridge, cpi.GetArgTypes(), implParameters))
					{
						Fail("bridge constraints");
						return false;
					}
				}
			}
			if (instantiatedMethodType.GetRetType() != PrimitiveTypeWrapper.VOID)
			{
				TypeWrapper Rt = instantiatedMethodType.GetRetType();
				TypeWrapper Ra = GetImplReturnType(implMethod);
				if (Ra == PrimitiveTypeWrapper.VOID || !IsAdaptable(Ra, Rt, true))
				{
					Fail("The return type Rt is void, or the return type Ra is not void and is adaptable to Rt");
					return false;
				}
			}
			MethodWrapper interfaceMethod = null;
			List<MethodWrapper> methods = new List<MethodWrapper>();
			foreach (MethodWrapper mw in methodList)
			{
				if (mw.Name == cpi.Name && mw.Signature == samMethodType.Signature)
				{
					interfaceMethod = mw;
					methods.Add(mw);
				}
				else if (mw.IsAbstract && !IsObjectMethod(mw))
				{
					methods.Add(mw);
				}
			}
			if (interfaceMethod == null || !interfaceMethod.IsAbstract || IsObjectMethod(interfaceMethod) || !MatchSignatures(interfaceMethod, samMethodType))
			{
				Fail("interfaceMethod");
				return false;
			}

			TypeBuilder tb = context.DefineAnonymousClass();
			// we're not implementing the interfaces recursively (because we don't care about .NET Compact anymore),
			// but should we decide to do that, we'd need to somehow communicate to AnonymousTypeWrapper what the 'real' interface is
			tb.AddInterfaceImplementation(interfaceType.TypeAsBaseType);
			if (serializable && Array.IndexOf(markers, CoreClasses.java.io.Serializable.Wrapper) == -1)
			{
				tb.AddInterfaceImplementation(CoreClasses.java.io.Serializable.Wrapper.TypeAsBaseType);
			}
			foreach (TypeWrapper marker in markers)
			{
				tb.AddInterfaceImplementation(marker.TypeAsBaseType);
			}
			ctor = CreateConstructorAndDispatch(context, cpi, tb, methods, implParameters, samMethodType, implMethod, instantiatedMethodType, serializable);
			AddDefaultInterfaceMethods(context, methodList, tb);
			return true;
		}