-
Notifications
You must be signed in to change notification settings - Fork 240
Update CSharpWriter to handle private fields in structs #1859
Update CSharpWriter to handle private fields in structs #1859
Conversation
if (resolvedType is Dummy) | ||
return true; | ||
|
||
foreach (var field in resolvedType.Fields) |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
Does this also check that the implementation is consistent with the contract; or does this just generate? |
Right now it is just generating. I will see if I can write up an APICompat rule for it but I think that is going to be even more complex to reason about. I did compare results between generating with coreclr vs uapaot. It generated the same results with the only difference being https://github.com/dotnet/corefx/pull/26264/files#diff-b3d39e42f75b9efe89d21eb385ed61f6R2001 RuntimeArgumentHandle where CoreCLR had a field and UAPAOT didn't. You can see the UAPAOT generated ref here weshaggard/corefx@ca4a3d3 if you are interested. |
// - If there are any private fields that are or contain any value type members, add a single private field of type int | ||
// - If there are any private fields that are or contain any reference type members, add a single private field of type object. | ||
// - If the type is generic, then for every type parameter of the type, if there are any private fields that are or contain any members whose type is that type parameter, we add a direct private field of that type. | ||
|
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
Ok, sounds good.
I would expect to have more differences. E.g. RuntimeTypeHandle should have object on CoreCLR and int on CoreRT. |
RuntimeTypeHandle on CoreRT has a EETypePtr which as a pointer field https://github.com/dotnet/corert/blob/master/src/System.Private.CoreLib/src/System/EETypePtr.cs#L27 so it gets flagged as being a reference and ends up with an object dummy field as well. |
For compile-time compat, the following rules should work for producing a reference assembly. We drop all private fields, but add back certain synthesized private fields for a value type (struct) as follows: - If there are any private fields that are or contain any value type members, add a single private field of type int - If there are any private fields that are or contain any reference type members, add a single private field of type object. - If the type is generic, then for every type parameter of the type, if there are any private fields that are or contain any members whose type is that type parameter, we add a direct private field of that type. For more details see issue https://github.com/dotnet/corefx/issues/6185 this blog is helpful as well http://blog.paranoidcoding.com/2016/02/15/are-private-members-api-surface.html
Unmanaged pointers should be treated as |
IsReferenceType is not always the inverse of IsValueType. Things like unmanaged pointer references aren't value types nor are they a managed reference type. Changed to use the logic already in CCI to detect a reference type but it requires a resolved type definition instead of a type reference.
91562b6
to
04124b3
Compare
@jkotas your right there are a few more differences in UAPAOT implementation. See weshaggard/corefx@71347e7 to see the diff between System.Runtime generated by CoreCLR and then generated by UAPAOT. I think the changes for CoreCLR are the most general and should handle the cases for UAPAOT as well, but let me know if you think there are any differences that are worrisome. |
The runtime treats ByReference<T> special as a ref T, so we need the tools to also treat it as a reference.
if (hasRefPrivateField) | ||
fieldType = parentType.PlatformType.SystemObject; | ||
|
||
// For primiative types that have a field of their type set the dummy field to that type |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
bool hasRefPrivateField = excludedFields.Any(f => f.Type.IsOrContainsReferenceType()); | ||
ITypeReference fieldType = parentType.PlatformType.SystemInt32; | ||
|
||
// If at least one the private fields contains a reference type then we need to |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
I have fixed differences that were just plain bugs in dotnet/corert#5238 |
For compile-time compat, the following rules should work for producing a reference assembly. We drop all private fields, but add back certain synthesized private fields for a value type (struct) as follows:
For more details see issue https://github.com/dotnet/corefx/issues/6185
this blog is helpful as well http://blog.paranoidcoding.com/2016/02/15/are-private-members-api-surface.html
PTAL @jkotas @VSadov @jaredpar @gafter
To get an idea of what is produced see the updated System.Runtime with dotnet/corefx@a2d4a32.