/// <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(new ProxyMethodContext(container), proxy.GetILGenerator(), null); ec.EmitThis(); // TODO: GetAllParametersArguments for (int i = 0; i < top; i++) { ec.EmitArgumentLoad(i); } ec.Emit(OpCodes.Call, base_method); ec.Emit(OpCodes.Ret); container.TypeBuilder.DefineMethodOverride(proxy, (MethodInfo)iface_method.GetMetaInfo()); }
public void EmitAddressOf(EmitContext ec) { if ((ModFlags & Modifier.RefOutMask) != 0) { ec.EmitArgumentLoad(idx); } else { ec.EmitArgumentAddress(idx); } }
protected override void DoEmit(EmitContext ec) { for (int i = 0; i < fields.Length; ++i) { var field = fields[i]; if (field == null) { continue; } ec.EmitArgumentLoad(thisParameterIndex); ec.EmitArgumentLoad(i); if (parametersTypes[i] is ReferenceContainer) { ec.EmitLoadFromPtr(field.MemberType); } ec.Emit(OpCodes.Stfld, field); } }
/// <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 (new ProxyMethodContext (container), proxy.GetILGenerator (), null); ec.EmitThis (); // TODO: GetAllParametersArguments for (int i = 0; i < top; i++) ec.EmitArgumentLoad (i); ec.Emit (OpCodes.Call, base_method); ec.Emit (OpCodes.Ret); container.TypeBuilder.DefineMethodOverride (proxy, (MethodInfo) iface_method.GetMetaInfo ()); }
public void EmitAddressOf (EmitContext ec) { if ((ModFlags & Modifier.RefOutMask) != 0) { ec.EmitArgumentLoad (idx); } else { ec.EmitArgumentAddress (idx); } }
public void Emit (EmitContext ec) { ec.EmitArgumentLoad (idx); }
public void Emit(EmitContext ec) { ec.EmitArgumentLoad(idx); }