Skip to content

Commit

Permalink
PR feedback
Browse files Browse the repository at this point in the history
- Remove new public APIs
- Remove most new native APIs
- Plumb GetUninitializedObject atop new native code paths
- Use actual builds from arcade
  • Loading branch information
GrabYourPitchforks committed Jul 8, 2020
1 parent 67539c2 commit edf3858
Show file tree
Hide file tree
Showing 17 changed files with 298 additions and 757 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,6 @@
<Compile Include="$(BclSourcesRoot)\System\Reflection\MemberInfo.Internal.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\Metadata\AssemblyExtensions.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\MethodBase.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\ObjectFactory.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\RtFieldInfo.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\RuntimeAssembly.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\RuntimeConstructorInfo.cs" />
Expand All @@ -209,7 +208,6 @@
<Compile Include="$(BclSourcesRoot)\System\Reflection\RuntimeModule.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\RuntimeParameterInfo.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\RuntimePropertyInfo.cs" />
<Compile Include="$(BclSourcesRoot)\System\Reflection\UninitializedObjectFactory.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Resources\ManifestBasedResourceGroveler.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\CrossLoaderAllocatorHashHelpers.cs" />
<Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\DependentHandle.cs" />
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -137,54 +137,25 @@ public static int OffsetToStringData
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern bool TryEnsureSufficientExecutionStack();

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern object GetUninitializedObjectInternal(
// This API doesn't call any constructors, but the type needs to be seen as constructed.
// A type is seen as constructed if a constructor is kept.
// This obviously won't cover a type with no constructor. Reference types with no
// constructor are an academic problem. Valuetypes with no constructors are a problem,
// but IL Linker currently treats them as always implicitly boxed.
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
Type type);

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern object AllocateUninitializedClone(object obj);

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern unsafe delegate*<MethodTable*, object> GetNewobjHelper(RuntimeType type);

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool IsFastInstantiable(RuntimeType type);

public static unsafe Func<object> GetUninitializedObjectFactory(Type type)
private static unsafe object GetUninitializedObjectInternal(Type type)
{
if (type is null)
{
throw new ArgumentNullException(nameof(type));
}
RuntimeType rt = (RuntimeType)type;
Debug.Assert(rt != null);

if (!(type.UnderlyingSystemType is RuntimeType rt))
{
throw new ArgumentException(SR.Arg_MustBeType, nameof(type));
}
// If somebody asks us to create a Nullable<T>, create a T instead.
delegate*<MethodTable*, object> newobjHelper = RuntimeTypeHandle.GetNewobjHelperFnPtr(rt, out MethodTable* pMT, unwrapNullable: true, allowCom: false);
Debug.Assert(newobjHelper != null);
Debug.Assert(pMT != null);

type = null!; // just to make sure we don't use Type for the rest of the method
object retVal = newobjHelper(pMT);
GC.KeepAlive(rt); // don't allow the type to be collected before the object is instantiated

if (rt.IsPointer || rt.IsByRef || rt.IsByRefLike || !RuntimeHelpers.IsFastInstantiable(rt))
{
throw new ArgumentException(
paramName: nameof(type),
message: SR.NotSupported_Type);
}

// Compat with GetUninitializedObject: if incoming type T is really
// Nullable<U>, then this factory should return a boxed default(U)
// instead of a boxed default(Nullable<U>).

rt = (RuntimeType?)Nullable.GetUnderlyingType(rt) ?? rt;
return (Func<object>)new UninitializedObjectFactory(rt).CreateUninitializedInstance;
return retVal;
}

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern object AllocateUninitializedClone(object obj);

/// <returns>true if given type is reference type or value type that contains references</returns>
[Intrinsic]
public static bool IsReferenceOrContainsReferences<T>()
Expand Down Expand Up @@ -384,6 +355,7 @@ internal unsafe struct MethodTable
private const uint enum_flag_Category_ValueType = 0x00040000;
private const uint enum_flag_Category_ValueType_Mask = 0x000C0000;
private const uint enum_flag_ContainsPointers = 0x01000000;
private const uint enum_flag_ComObject = 0x40000000;
private const uint enum_flag_HasComponentSize = 0x80000000;
private const uint enum_flag_HasDefaultCtor = 0x00000200;
private const uint enum_flag_HasTypeEquivalence = 0x00004000; // TODO: shouldn't this be 0x02000000?
Expand Down Expand Up @@ -451,6 +423,14 @@ public bool HasDefaultConstructor
}
}

public bool IsComObject
{
get
{
return (Flags & enum_flag_ComObject) != 0;
}
}

public bool IsNullable
{
get
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,32 @@ internal static bool HasElementType(RuntimeType type)
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern object CreateInstanceForAnotherGenericParameter(RuntimeType type, RuntimeType genericParameter);

/// <summary>
/// Given a RuntimeType, returns both the address of the JIT's newobj helper for that type and the
/// MethodTable* corresponding to that type. If the type is <see cref="Nullable{T}"/> closed over
/// some T and <paramref name="unwrapNullable"/> is true, then returns the values for the 'T'.
/// </summary>
internal static delegate*<MethodTable*, object> GetNewobjHelperFnPtr(RuntimeType type, out MethodTable* pMT, bool unwrapNullable, bool allowCom)
{
Debug.Assert(type != null);

delegate*<MethodTable*, object> pNewobjHelperTemp = null;
MethodTable* pMTTemp = null;

GetNewobjHelperFnPtr(
new QCallTypeHandle(ref type),
&pNewobjHelperTemp,
&pMTTemp,
(unwrapNullable) ? Interop.BOOL.TRUE : Interop.BOOL.FALSE,
(allowCom) ? Interop.BOOL.TRUE : Interop.BOOL.FALSE);

pMT = pMTTemp;
return pNewobjHelperTemp;
}

[DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)]
private static extern void GetNewobjHelperFnPtr(QCallTypeHandle typeHandle, delegate*<MethodTable*, object>* ppNewobjHelper, MethodTable** ppMT, Interop.BOOL fUnwrapNullable, Interop.BOOL fAllowCom);

internal RuntimeType GetRuntimeType()
{
return m_type;
Expand Down Expand Up @@ -249,12 +275,6 @@ public ModuleHandle GetModuleHandle()
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern RuntimeMethodHandleInternal GetMethodAt(RuntimeType type, int slot);

[MethodImpl(MethodImplOptions.InternalCall)]
internal static unsafe extern MethodTable* GetMethodTable(RuntimeType type);

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern RuntimeMethodHandleInternal GetDefaultConstructor(RuntimeType type);

// This is managed wrapper for MethodTable::IntroducedMethodIterator
internal struct IntroducedMethodEnumerator
{
Expand Down
Loading

0 comments on commit edf3858

Please sign in to comment.