private MethodInfo CreateErrorStub(EmitIntrinsicContext context, TypeWrapper targetType, bool isAbstract) { MethodInfo invoke = delegateConstructor.DeclaringType.GetMethod("Invoke"); ParameterInfo[] parameters = invoke.GetParameters(); Type[] parameterTypes = new Type[parameters.Length + 1]; parameterTypes[0] = Types.Object; for (int i = 0; i < parameters.Length; i++) { parameterTypes[i + 1] = parameters[i].ParameterType; } MethodBuilder mb = context.Context.DefineDelegateInvokeErrorStub(invoke.ReturnType, parameterTypes); CodeEmitter ilgen = CodeEmitter.Create(mb); ilgen.EmitThrow(isAbstract ? "java.lang.AbstractMethodError" : "java.lang.IllegalAccessError", targetType.Name + ".Invoke" + iface.GetMethods()[0].Signature); ilgen.DoEmit(); return mb; }
internal virtual bool EmitIntrinsic(EmitIntrinsicContext context) { return Intrinsics.Emit(context); }
internal override bool EmitIntrinsic(EmitIntrinsicContext context) { TypeWrapper targetType = context.GetStackTypeWrapper(0, 0); if (targetType.IsUnloadable || targetType.IsInterface) { return false; } // we know that a DelegateInnerClassTypeWrapper has only one method Debug.Assert(iface.GetMethods().Length == 1); MethodWrapper mw = targetType.GetMethodWrapper(GetDelegateInvokeStubName(DeclaringType.TypeAsTBD), iface.GetMethods()[0].Signature, true); if (mw == null || mw.IsStatic || !mw.IsPublic) { context.Emitter.Emit(OpCodes.Ldftn, CreateErrorStub(context, targetType, mw == null || mw.IsStatic)); context.Emitter.Emit(OpCodes.Newobj, delegateConstructor); return true; } // TODO linking here is not safe mw.Link(); context.Emitter.Emit(OpCodes.Dup); context.Emitter.Emit(OpCodes.Ldvirtftn, mw.GetMethod()); context.Emitter.Emit(OpCodes.Newobj, delegateConstructor); return true; }