Skip to content
This repository has been archived by the owner on Jan 11, 2024. It is now read-only.

Update CSharpWriter to handle private fields in structs #1859

Merged
merged 6 commits into from
Jan 12, 2018

Conversation

weshaggard
Copy link
Member

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

PTAL @jkotas @VSadov @jaredpar @gafter

To get an idea of what is produced see the updated System.Runtime with dotnet/corefx@a2d4a32.

if (resolvedType is Dummy)
return true;

foreach (var field in resolvedType.Fields)

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

@jkotas
Copy link
Member

jkotas commented Jan 11, 2018

Does this also check that the implementation is consistent with the contract; or does this just generate?

@weshaggard
Copy link
Member Author

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.

This comment was marked as spam.

@jkotas
Copy link
Member

jkotas commented Jan 11, 2018

Right now it is just generating.

Ok, sounds good.

RuntimeArgumentHandle where CoreCLR had a field and UAPAOT didn't

I would expect to have more differences. E.g. RuntimeTypeHandle should have object on CoreCLR and int on CoreRT.

@weshaggard
Copy link
Member Author

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
@jkotas
Copy link
Member

jkotas commented Jan 11, 2018

RuntimeTypeHandle on CoreRT has a EETypePtr which as a pointer

Unmanaged pointers should be treated as int. They should not be treated as object.

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.
@weshaggard weshaggard force-pushed the UpdateToolsToHandleStructFields branch from 91562b6 to 04124b3 Compare January 11, 2018 18:16
@weshaggard
Copy link
Member Author

@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.

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.

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.

@jkotas
Copy link
Member

jkotas commented Jan 12, 2018

to see the diff between System.Runtime generated by CoreCLR and then generated by UAPAOT

I have fixed differences that were just plain bugs in dotnet/corert#5238

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants