// // Emits the code // public virtual void Emit (TypeContainer parent, Block block, object kind) { ILGenerator ig; EmitContext ec; if ((flags & MethodAttributes.PinvokeImpl) == 0) ig = builder.GetILGenerator (); else ig = null; ec = new EmitContext (parent, Location, ig, ReturnType, modifiers); if (OptAttributes != null) Attribute.ApplyAttributes (ec, builder, kind, OptAttributes); if (member is MethodCore) ((MethodCore) member).LabelParameters (ec, MethodBuilder, OptAttributes); // // abstract or extern methods have no bodies // if ((modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0){ if (block == null) { SymbolWriter sw = CodeGen.SymbolWriter; if ((sw != null) && ((modifiers & Modifiers.EXTERN) != 0)) { sw.OpenMethod (parent, MethodBuilder, Location, Location); sw.CloseMethod (); } return; } // // abstract or extern methods have no bodies. // if ((modifiers & Modifiers.ABSTRACT) != 0) Report.Error ( 500, Location, "Abstract method `" + TypeManager.CSharpSignature (builder) + "' can not have a body"); if ((modifiers & Modifiers.EXTERN) != 0) Report.Error ( 179, Location, "External method `" + TypeManager.CSharpSignature (builder) + "' can not have a body"); return; } // // Methods must have a body unless they're extern or abstract // if (block == null) { Report.Error ( 501, Location, "Method `" + TypeManager.CSharpSignature (builder) + "' must declare a body since it is not marked " + "abstract or extern"); return; } // // Handle destructors specially // // FIXME: This code generates buggy code // if (member.Name == "Finalize" && ReturnType == TypeManager.void_type) EmitDestructor (ec, block); else { SymbolWriter sw = CodeGen.SymbolWriter; if ((sw != null) && !Location.IsNull (Location) && !Location.IsNull (block.EndLocation)) { sw.OpenMethod (parent, MethodBuilder, Location, block.EndLocation); ec.EmitTopBlock (block, ParameterInfo, Location); sw.CloseMethod (); } else ec.EmitTopBlock (block, ParameterInfo, Location); } }
void EmitDestructor (EmitContext ec, Block block) { ILGenerator ig = ec.ig; Label finish = ig.DefineLabel (); bool old_in_try = ec.InTry; ig.BeginExceptionBlock (); ec.InTry = true; ec.ReturnLabel = finish; ec.HasReturnLabel = true; ec.EmitTopBlock (block, null, Location); ec.InTry = old_in_try; // ig.MarkLabel (finish); bool old_in_finally = ec.InFinally; ec.InFinally = true; ig.BeginFinallyBlock (); if (ec.ContainerType.BaseType != null) { Expression member_lookup = Expression.MemberLookup ( ec, ec.ContainerType.BaseType, null, ec.ContainerType.BaseType, "Finalize", MemberTypes.Method, Expression.AllBindingFlags, Location); if (member_lookup != null){ MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup); ig.Emit (OpCodes.Ldarg_0); ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]); } } ec.InFinally = old_in_finally; ig.EndExceptionBlock (); //ig.MarkLabel (ec.ReturnLabel); ig.Emit (OpCodes.Ret); }
// // Emits the code // public void Emit (TypeContainer parent) { ILGenerator ig = ConstructorBuilder.GetILGenerator (); EmitContext ec = new EmitContext (parent, Location, ig, null, ModFlags, true); // // extern methods have no bodies // if ((ModFlags & Modifiers.EXTERN) != 0) { if ((block != null) && ((ModFlags & Modifiers.EXTERN) != 0)) { Report.Error ( 179, Location, "External constructor `" + TypeManager.CSharpSignature (ConstructorBuilder) + "' can not have a body"); return; } } else if (block == null) { Report.Error ( 501, Location, "Constructor `" + TypeManager.CSharpSignature (ConstructorBuilder) + "' must declare a body since it is not marked extern"); return; } if ((ModFlags & Modifiers.STATIC) == 0){ if (parent is Class && Initializer == null) Initializer = new ConstructorBaseInitializer ( null, Parameters.EmptyReadOnlyParameters, Location.Null); // // Spec mandates that Initializers will not have // `this' access // ec.IsStatic = true; if (Initializer != null && !Initializer.Resolve (ec)) return; ec.IsStatic = false; } LabelParameters (ec, ConstructorBuilder, OptAttributes); SymbolWriter sw = CodeGen.SymbolWriter; bool generate_debugging = false; if ((sw != null) && (block != null) && !Location.IsNull (Location) && !Location.IsNull (block.EndLocation)) { sw.OpenMethod (parent, ConstructorBuilder, Location, block.EndLocation); generate_debugging = true; } // // Classes can have base initializers and instance field initializers. // if (parent is Class){ if ((ModFlags & Modifiers.STATIC) == 0) parent.EmitFieldInitializers (ec); } if (Initializer != null) Initializer.Emit (ec); if ((ModFlags & Modifiers.STATIC) != 0) parent.EmitFieldInitializers (ec); Attribute.ApplyAttributes (ec, ConstructorBuilder, this, OptAttributes); // If this is a non-static `struct' constructor and doesn't have any // initializer, it must initialize all of the struct's fields. if ((parent is Struct) && ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null)) Block.AddThisVariable (parent, Location); ec.EmitTopBlock (block, ParameterInfo, Location); if (generate_debugging) sw.CloseMethod (); block = null; }