-
-
Notifications
You must be signed in to change notification settings - Fork 3.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
Replace RuntimeHelpers.CreateSpan<T>(LdMemberToken)
with new T[] { }
#3380
base: master
Are you sure you want to change the base?
Replace RuntimeHelpers.CreateSpan<T>(LdMemberToken)
with new T[] { }
#3380
Conversation
#if !NET40 && ROSLYN | ||
public static ReadOnlySpan<byte> ReadOnlySpanInitializer_ByteArray() | ||
{ | ||
return new byte[] { 1, 2, 3 }; | ||
} | ||
|
||
public static ReadOnlySpan<int> ReadOnlySpanInitializer_Int32Array() | ||
{ | ||
return new int[] { 1, 2, 3 }; | ||
} | ||
#endif | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I have put these in a new file and modified the options? It currently fails for Roslyn v1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason why these tests are "correctness" tests and not "pretty" tests?
It seems like this is a relatively new language feature... you can simply use the CSx
preprocessor symbol that matches the earliest version of C# where this feature is supported.
@@ -143,6 +143,40 @@ internal static bool TransformSpanTArrayInitialization(NewObj inst, StatementTra | |||
return false; | |||
} | |||
|
|||
internal static bool TransformRuntimeHelpersCreateSpanInitialization(Call inst, StatementTransformContext context, out ILInstruction replacement) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thoughts on the method name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really, I am bad at naming things... 😅 ... luckily I had nine months to name my children...
if (context.Settings.Utf8StringLiterals && | ||
elementType.IsKnownType(KnownTypeCode.Byte) && | ||
DecodeUTF8String(initialValue, size, out string text)) | ||
{ | ||
replacement = new LdStrUtf8(text); | ||
return true; | ||
} | ||
if (DecodeArrayInitializer(elementType, initialValue, new[] { size }, valuesList)) | ||
{ | ||
var tempStore = context.Function.RegisterVariable(VariableKind.InitializerTarget, new ArrayType(context.TypeSystem, elementType)); | ||
replacement = BlockFromInitializer(tempStore, elementType, new[] { size }, valuesList.ToArray()); | ||
return true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the same as for Span<T>(void*, int)
handler. Should split this out into a shared function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could do that, yes...
field = default; | ||
elementType = null; | ||
IType type = inst.Method.DeclaringType; | ||
if (type.Namespace != "System.Runtime.CompilerServices" || type.Name != "RuntimeHelpers" || type.TypeParameterCount != 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the right way to check? Should I have created a "known" type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There already exists
static bool IsRuntimeHelpers(IType type) => type is { Name: "RuntimeHelpers", Namespace: "System.Runtime.CompilerServices" }; |
Although that's missing the check for TypeParameterCount
, but you could add it.
I don't think it's necessary to add a known type for this...
if (inst.Arguments.Count != 1) | ||
return false; | ||
IMethod method = inst.Method; | ||
if (method.Name != "CreateSpan" || method.TypeArguments.Count != 1) | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I be checking the full method signature? I noticed that the other handler doesn't check argument types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
checking more is usually better than checking less... note that the code in that file is very old and thus is not using some of the helpers and is not following the style of later transform implementations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addendum: for methods we usually check the name, the number of parameters and then validate all the arguments, so checking the parameter types is usually not necessary.
Problem
Resolves #3379
Solution
Span<T>(void*, int)
.