Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New API: ModuleInitializerAttribute #35749

Closed
jnm2 opened this issue May 2, 2020 · 9 comments · Fixed by #37625
Closed

New API: ModuleInitializerAttribute #35749

jnm2 opened this issue May 2, 2020 · 9 comments · Fixed by #37625
Labels
api-approved API was approved in API review, it can be implemented area-System.Runtime.CompilerServices untriaged New issue has not been triaged by the area owner
Milestone

Comments

@jnm2
Copy link
Contributor

jnm2 commented May 2, 2020

The module initializers feature for C# 9 enables a new attribute, [ModuleInitializer], to be applied to any number of static methods in a compilation. The marked methods are guaranteed to run before any other method is invoked or field is accessed in the whole module.

Usage example:

using System.Runtime.CompilerServices;

class C
{
    [ModuleInitializer]
    internal static void M()
    {
        // This code runs before any other code in the module
    }
}

API proposal

using System;

namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public sealed class ModuleInitializerAttribute : Attribute { }
}

Compiler behavior

Module initializer methods (methods marked with [ModuleInitializer]) must be:

  • accessible outside the top-level containing type
  • ordinary member methods (not accessors, finalizers, operators, or local functions, even though AttributeTargets.Method includes these)
  • static, parameterless, and void-returning
  • not generic and not contained by a generic type

If any methods match these criteria, a module initializer (runtime term for <Module>..cctor) is emitted. This is a special static constructor that has additional runtime guarantees. It will execute before any other field access or method invocation within the entire module. The emitted body is a series of call instructions, one to each module initializer method in a deterministic but undefined order, followed by a ret instruction.

The VB strategy has not been determined. It would either behave the same way or error when System.Runtime.CompilerServices.ModuleInitializerAttribute is applied to a method.

References

Language proposal (credit to @RikkiGibson) with link to meeting notes:
https://github.com/dotnet/csharplang/blob/master/proposals/module-initializers.md

Compiler feature doc (credit to @RikkiGibson):
https://github.com/dotnet/roslyn/blob/mi-feature-doc/docs/features/module-initializers.md

Runtime spec: https://github.com/dotnet/runtime/blob/master/docs/design/specs/Ecma-335-Augments.md#module-initializer

Test plan umbrella: dotnet/roslyn#40500
Implementation underway: https://github.com/dotnet/roslyn/commits/features/module-initializers

@Dotnet-GitSync-Bot
Copy link
Collaborator

I couldn't figure out the best area label to add to this issue. Please help me learn by adding exactly one area label.

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added the untriaged New issue has not been triaged by the area owner label May 2, 2020
@GrabYourPitchforks GrabYourPitchforks added this to the 5.0 milestone May 2, 2020
@GrabYourPitchforks GrabYourPitchforks added the blocking Marks issues that we want to fast track in order to unblock other important work label May 2, 2020
@jaredpar
Copy link
Member

@GrabYourPitchforks what does the "blocking" label signify here?

@eerhardt
Copy link
Member

It puts this issue to the front of the api-ready-for-review queue. The API Review meetings first review API requests that are labeled "blocking" before reviewing other requests.

@terrajobst terrajobst added api-approved API was approved in API review, it can be implemented and removed api-ready-for-review blocking Marks issues that we want to fast track in order to unblock other important work labels May 29, 2020
@terrajobst
Copy link
Member

terrajobst commented May 29, 2020

Video

@jaredpar presumably this feature won't have language syntax. Normally we don't use System.Runtime.CompilerServices for stuff that developers are expected to use directly. Normally, the namespace is for stuff the compiler generates calls for. However, in this case it seems on par with other very advanced features that we don't want the general public to use, so this feels OK.

namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public sealed class ModuleInitializerAttribute : Attribute
    {
    }
}

@RikkiGibson
Copy link
Contributor

What are next steps? Are we ready to open a PR to dotnet/runtime to add the API?

@jaredpar
Copy link
Member

Yeah this is meant for really advanced users, not main stream use hence this namespace feels fine to me.

@terrajobst
Copy link
Member

terrajobst commented May 29, 2020

@RikkiGibson

What are next steps? Are we ready to open a PR to dotnet/runtime to add the API?

That is probably the easiest solution. You could ask @danmosemsft for a dev but attributes are basically trivial.

@jkotas
Copy link
Member

jkotas commented May 29, 2020

You can use #454 as a template.

@jaredpar
Copy link
Member

We'd planned on having @RikkiGibson do the work here so we'll get a PR out soon-ish for this.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented area-System.Runtime.CompilerServices untriaged New issue has not been triaged by the area owner
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants