public void EmitAddressOf(EmitContext ec) { int arg_idx = idx; if (!ec.IsStatic) { arg_idx++; } bool is_ref = (ModFlags & Modifier.ISBYREF) != 0; if (is_ref) { ParameterReference.EmitLdArg(ec, arg_idx); } else { if (arg_idx <= 255) { ec.Emit(OpCodes.Ldarga_S, (byte)arg_idx); } else { ec.Emit(OpCodes.Ldarga, arg_idx); } } }
/// <summary> /// C# allows this kind of scenarios: /// interface I { void M (); } /// class X { public void M (); } /// class Y : X, I { } /// /// For that case, we create an explicit implementation function /// I.M in Y. /// </summary> void DefineProxy(TypeSpec iface, MethodSpec base_method, MethodSpec iface_method) { // TODO: Handle nested iface names string proxy_name; var ns = iface.MemberDefinition.Namespace; if (string.IsNullOrEmpty(ns)) { proxy_name = iface.MemberDefinition.Name + "." + iface_method.Name; } else { proxy_name = ns + "." + iface.MemberDefinition.Name + "." + iface_method.Name; } var param = iface_method.Parameters; MethodBuilder proxy = container.TypeBuilder.DefineMethod( proxy_name, MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride | MethodAttributes.Virtual | MethodAttributes.Final, CallingConventions.Standard | CallingConventions.HasThis, base_method.ReturnType.GetMetaInfo(), param.GetMetaInfo()); if (iface_method.IsGeneric) { var gnames = iface_method.GenericDefinition.TypeParameters.Select(l => l.Name).ToArray(); proxy.DefineGenericParameters(gnames); } for (int i = 0; i < param.Count; i++) { string name = param.FixedParameters [i].Name; ParameterAttributes attr = ParametersCompiled.GetParameterAttribute(param.FixedParameters [i].ModFlags); proxy.DefineParameter(i + 1, attr, name); } int top = param.Count; var ec = new EmitContext(null, proxy.GetILGenerator(), null); // TODO: GetAllParametersArguments for (int i = 0; i <= top; i++) { ParameterReference.EmitLdArg(ec, i); } ec.Emit(OpCodes.Call, base_method); ec.Emit(OpCodes.Ret); container.TypeBuilder.DefineMethodOverride(proxy, (MethodInfo)iface_method.GetMetaInfo()); }
public void Emit(EmitContext ec) { int arg_idx = idx; if (!ec.IsStatic) { arg_idx++; } ParameterReference.EmitLdArg(ec, arg_idx); }
/// <summary> /// C# allows this kind of scenarios: /// interface I { void M (); } /// class X { public void M (); } /// class Y : X, I { } /// /// For that case, we create an explicit implementation function /// I.M in Y. /// </summary> void DefineProxy(Type iface, MethodInfo base_method, MethodInfo iface_method, AParametersCollection param) { // TODO: Handle nested iface names string proxy_name = SimpleName.RemoveGenericArity(iface.FullName) + "." + iface_method.Name; MethodBuilder proxy = container.TypeBuilder.DefineMethod( proxy_name, MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride | MethodAttributes.Virtual, CallingConventions.Standard | CallingConventions.HasThis, base_method.ReturnType, param.GetEmitTypes()); Type[] gargs = TypeManager.GetGenericArguments(iface_method); if (gargs.Length > 0) { string[] gnames = new string[gargs.Length]; for (int i = 0; i < gargs.Length; ++i) { gnames[i] = gargs[i].Name; } #if GMCS_SOURCE proxy.DefineGenericParameters(gnames); #else throw new NotSupportedException(); #endif } for (int i = 0; i < param.Count; i++) { string name = param.FixedParameters [i].Name; ParameterAttributes attr = ParametersCompiled.GetParameterAttribute(param.FixedParameters [i].ModFlags); proxy.DefineParameter(i + 1, attr, name); } int top = param.Count; ILGenerator ig = proxy.GetILGenerator(); for (int i = 0; i <= top; i++) { ParameterReference.EmitLdArg(ig, i); } ig.Emit(OpCodes.Call, base_method); ig.Emit(OpCodes.Ret); container.TypeBuilder.DefineMethodOverride(proxy, iface_method); }