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

Hot Reload: Allow extern functions to be added #73421

Open
lambdageek opened this issue May 10, 2024 · 2 comments
Open

Hot Reload: Allow extern functions to be added #73421

lambdageek opened this issue May 10, 2024 · 2 comments
Labels
Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead

Comments

@lambdageek
Copy link
Member

lambdageek commented May 10, 2024

The [UnsafeAccessorAttribute] (API Proposal) is used on static extern functions to instruct the .NET runtime to generate an accessor method to a type member that bypass the normal .NET visibility checks.

   public class MyClass
   {
      private int _hidden;
      ...
    }

    public static partial class AccessHelpers
    {
        [UnsafeAccessor(UnsafeAccessorKind.Field, Name="_hidden")]
        public static extern ref int GetHiddenField(MyClass c);    // runtime generated implementation
    }

    ...

    public static MyClass DeserializeMyClass(string s)
    {
        MyClass x = new MyClass();
        ref int hiddenFieldRef = ref AccessHelpers.GetHiddenField(x);
        hiddenFieldRef = int.Parse(s);
        return x;
     }    
}

With [UnsafeAccessor] it becomes possible to use source-generated reflection-free serializers that can serialize and deserialize fields of user-defined classes. For example, a user may add a new field _hidden to MyClass and the source generator will add a new accessor method to AccessHelpers and generate a method DeserializeMyClass that uses the access method to populate the hidden field.

Currently if the user adds a second private field _hidden2 and the generator adds a new static extern method, EnC will report a rude edit:

error ENC0025: Adding an extern method requires restarting the application.

Note that both AccessHelpers or the static extern method could be generic:

public class MyContainer<T>
{
   private T[] _elements;
}

public static AccessHelpers<T>
{
   [UnsafeAccessor(UnsafeAccessorKind.Field, Name="_elements")]
   public static extern ref T[] GetElements(MyContainer<T> container);
}

public static AccessHelpers2
{
   [UnsafeAccessor(UnsafeAccessorKind.Field, Name="_elements")]
   public static extern ref T[] GetElements<T>(MyContainer<T> container);
}

The runtime support is tracked in dotnet/runtime#102080

@lambdageek
Copy link
Member Author

/cc @tmat

@lambdageek
Copy link
Member Author

lambdageek commented May 10, 2024

Note these are not P/Invokes. extern functions dont' have any special flags set. Instead they just don't have a method body RVA (and thus no method header or IL)

Compare C.PInvoke vs C.StaticExtern vs C.NormalStatic: https://sharplab.io/#v2:EYLgtghglgdgNAFxFANgHwAICYCMBYAKAwAYACDHAOgCUBXGBKMAU0oEkHmAnAewAcAytwBuUAMbMAzgG5ChDAGZyOAGzkspAMKkA3oVIHSAbQAiKFGzB8eXBAAoARAA0AmgC0AMlGAOAlAF19Q0VlNWYADwRuGHIAFlIABQ5hHgBrZjtfWQJDUiCDEIowyOi40gEECEYxAFESrhhM7Nz88iUisoA5G0gUCqrxTN0AX0JhoA

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead
Projects
None yet
Development

No branches or pull requests

2 participants