-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Open Issues in "Function Pointers" #39865
Comments
@jkotas, @AaronRobinsonMSFT, @jkoritzinsky. Could one of you comment on the custom attributes question and how this would work or if it is something that will likely never be supported? |
It is likely that will need to support new calling conventions, or flags on the existing calling conventions, in future. The current design does not have an obvious way to do that is unfortunate. There are two parts of the problem:
|
Just to expand on my example in 1: The expression following
|
Also, I think doing something about 1 now is more important than doing something about 2 now. We can add 2 later without introducing ugly user facing warts. But if we do not do something about 1 now, we will likely need to always change Roslyn for any calling convention addition. |
For 1, I think we can make something work if we get a definition in ECMA-335 for extensible calling conventions. The proposal I'd have would be something like this:
We could also potentially use this format to encode things like SuppressGCTransition. If we want to start marking things other than the calling convention, though, I do think we'll want some new syntax form. For both of these things, I personally see them as things that can happen after we ship the initial version of function pointers. The extensible calling convention bit is transparent to users, and the SuppressGCTransition stuff will need new syntactic forms that will need to go through LDM. |
/cc @AlekseyTs as well. |
What do you mean by platform in this context? Platform typically means OS, but I do not think you meant that.
These attributes do exist for managed C++ already (
The fewer names we have for the same thing the better. Can it be 1:1 mapping? E.g. assuming we would use the existing types:
What is the new syntax form you would propose?
I am worried that the new syntactic form won't work well with the shipped syntactic form. |
I think we need to settle on particular aspect: is the explicit goal to support attributes like If this is an explicit future goal then we need to plan for it. Neither our current syntax form nor the underlying runtime ABI that we depend on will support it (to my understanding at least). If this is an explicit request does the runtime have a proposal for the underlying ABI changes that we can look at to evaluate the path forward? Appologies if this has been communicated in a forum I'm unaware of (or if I just deleted the email on accident). 😦 |
@jaredpar I think that is a very fair assessment. The general feeling is that we know there are a myriad of calling conventions that we may want to support. Which ones is basically an unknown, but the fact they exist is something we want users to be able to communicate to the runtime through the function pointer syntax since language features aren't simple to quickly get through. So this is merely for let's make sure all calling conventions have a possible path forward. The above is probably an agreed upon stance with little debate. The concept of additional attributes (e.g. I don't think we have any additional example other than the existing |
Agree with @AaronRobinsonMSFT
This is a new attribute that we have not shipped as stable yet. We have still opportunity to change how it is done to work better with the other features if necessary.
Attributes cannot be represented in natural way to function pointers in IL metadata today. It is what makes the attribute-centric approach problematic... |
I will say that I do like the extensibility of the I think @jkotas' design around defining a simple mapping from a "context-sensitive keyword" to a modreq of a type in System.Runtime.CompilerServices named |
I think it can be used to cover the calling convention, but I don't think it can be used to cover other attributes. |
Since any attributes on function pointers would only have any effect at the call site, I think they should be part of the function pointer type. Otherwise the attribute could be implicitly lost through assignment or being passed as a parameter. |
Where would that be encoded in metadata? There isn't an actual typedef for
and I don't believe you can attach an attribute to a So the problem is the user has
There is a section on assignment compatibility, which (if I read it correctly) says the modreq can be ignored, but I don't think that would change the signature compatibility of a method between v1 and v2 of a library. |
@tannergooding do you have a documentation link, an issue, etc ... anything concrete you can show us that describes |
I do understand the issues around calling convention and extensibility. I think my team has enough to go on there to look for better solutions. It's definitely on the list of items we need to solve before RTM. So it's an open issue but one that we understand the ramifications around and can iterate no solve a solution. I'm less clear on how to move forward on attributes as an extensible feature. |
Right, I agree that attributes do not naturally work for function pointers. They should not be the solution for the encoding this info metadata that we lead with. modops/modreqs sound more workable as the metadata encoding for function pointers. |
By platform here I meant runtime.
Sure, I think this would work. The only issue I see is that we have a
C# doesn't capitalize keywords, so I don't think that would work. We could do a pattern-based approach where we substring the |
Meeting notes (with @jaredpar, @AlekseyTs, @jkotas, @AaronRobinsonMSFT, @tannergooding, and @333fred):
|
@jkotas @AaronRobinsonMSFT @tannergooding @jaredpar @AlekseyTs one small update to that proposal: The existing calling convention types are of this format:
Does this make sense to everyone? We'll discuss this point in LDM tomorrow. |
That makes sense to me. CC @terrajobst and @dotnet/fxdc as they are the general reviewers/approvers of API design decisions. |
@AaronRobinsonMSFT might be able to comment if there is any edge case I am not thinking about and what behavior |
I think my confusion comes from calling |
@333fred I've started using function pointers for C#/WinRT and I've run into an issue. I can't cast an "address-of-method-group" for a non-overloaded static function to |
@jkoritzinsky that's intended behavior, and the non-overloaded mention in the spec will be removed when I'm back from vacation next week. You will have to either assign it to a variable or cast it to a compatible function pointer type first. |
Ok. That's understandable. Do you have an ETA on supporting UnmanagedCallersOnly? I'd really like to avoid having to do multiple iterations to work around feature deficiencies since some of the code I'm working on isn't auto-generated. |
For reference since I missed it the first time as well, It might be nice in some future version to allow |
@tannergooding Eric Lippert actually blogged about that: https://docs.microsoft.com/en-us/archive/blogs/ericlippert/in-foof-we-trust-a-dialogue |
Right, it isn't necessarily easy, hence nice, etc 😄 |
Open issues for LDM 6/24: Function pointer calling convention syntax: func_ptr_calling_convention
: 'managed'
| 'unmanaged' '[' func_ptr_callkind ']'?
func_ptr_callkind
: 'CallConvCdecl'
| 'CallConvStdcall'
| 'CallConvThiscall'
| 'CallConvFastcall'
| identifier (',' identifier)*
|
What does this mean? When would it happen? |
i.e. could you write:
Note: IMO this syntax is just getting heinous. |
version used: unsafe class FunctionPointer
{
public static void M()
{
delegate*<void> a = &Static;
a(); // OK
a = &local;
a(); // Method not found: 'Void FunctionPointer.local()'.
static void local() => System.Console.WriteLine("local");
}
static void Static() => System.Console.WriteLine("static");
} |
A MethodRefSig or a StandaloneSig can have the calling convention "unmanaged" which is the default platform calling convention with optional modifiers encoded in the modopts of the return type. See dotnet/roslyn#39865 (comment) and dotnet/runtime#34805 Contributes to dotnet/runtime#38480
Probably, it's reasonable to allow the usage of static anonymous function as a value of function pointer type: delegate*<int, string> toStr = &static i => i.ToString(); |
@sakno That would require a language change. There's an existing proposal for it here: dotnet/csharplang#3476 |
Tracking issue for open function pointer questions:
Compilers
Presumably, the compiler is currently planning on emitting these types directly as FNPTR type signatures. However, the runtime doesn't currently have any way to attach attributes to such type signatures.
Has this been taken into consideration since that would make it a breaking change to go from the inline function pointer syntax (the only thing available today) to change to some syntax that allows attributes?
From @tannergooding, Update function pointer proposal with LDM changes csharplang#2923 (comment)
void*
for single-method method group with no type.IDE
Runtime changes
NativeCallableAttributeUnmanagedCallersOnlyAttribute
Make NativeCallableAttribute public. runtime#33005 (comment)The text was updated successfully, but these errors were encountered: