Integrate changes from NativeAOT branch (#53650)
authorJan Kotas <jkotas@microsoft.com>
Thu, 3 Jun 2021 12:58:33 +0000 (05:58 -0700)
committerGitHub <noreply@github.com>
Thu, 3 Jun 2021 12:58:33 +0000 (05:58 -0700)
* Integrate changes from NativeAOT branch

Includes faster virtual method enumerator that should help crossgen2 too

* Fix tests

21 files changed:
src/coreclr/tools/Common/TypeSystem/Common/ArrayType.cs
src/coreclr/tools/Common/TypeSystem/Common/ExceptionStringID.cs
src/coreclr/tools/Common/TypeSystem/Common/InstantiatedType.cs
src/coreclr/tools/Common/TypeSystem/Common/MetadataVirtualMethodAlgorithm.cs
src/coreclr/tools/Common/TypeSystem/Common/Properties/Resources.resx
src/coreclr/tools/Common/TypeSystem/Common/ThrowHelper.cs
src/coreclr/tools/Common/TypeSystem/Common/TypeDesc.cs
src/coreclr/tools/Common/TypeSystem/Common/TypeSystemContext.cs
src/coreclr/tools/Common/TypeSystem/Common/TypeSystemException.cs
src/coreclr/tools/Common/TypeSystem/Common/TypeSystemHelpers.cs
src/coreclr/tools/Common/TypeSystem/Common/Utilities/DebugNameFormatter.cs
src/coreclr/tools/Common/TypeSystem/Ecma/EcmaType.cs
src/coreclr/tools/Common/TypeSystem/Ecma/SymbolReader/PortablePdbSymbolReader.cs
src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs
src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs
src/coreclr/tools/Common/TypeSystem/Interop/MarshalAsDescriptor.cs
src/coreclr/tools/Common/TypeSystem/RuntimeDetermined/RuntimeDeterminedType.cs
src/coreclr/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SyntheticVirtualOverrideTests.cs
src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackFrame.cs
src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackTrace.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionMemberAccessor.cs

index c3e227ed3f6bbbb43f7623ff0c09f852dd4371fd..c21ba9342e198027ca56186f76b334b8257fbeac 100644 (file)
@@ -119,6 +119,11 @@ namespace Internal.TypeSystem
             return _methods;
         }
 
+        public override IEnumerable<MethodDesc> GetVirtualMethods()
+        {
+            return MethodDesc.EmptyMethods;
+        }
+
         public MethodDesc GetArrayMethod(ArrayMethodKind kind)
         {
             if (_methods == null)
index dd38a715c5fe2a97ea44ecb97d31dcd4c680c5b3..ab093a379d20db9386db801eca0db1efa281e504 100644 (file)
@@ -41,5 +41,8 @@ namespace Internal.TypeSystem
         // BadImageFormatException
         BadImageFormatGeneric,
         BadImageFormatSpecific,
+
+        // MarshalDirectiveException
+        MarshalDirectiveGeneric,
     }
 }
index 8d9d18c1a99f0dc0e5836e8f660f0e5e3ccefc95..f1164b677e20af6a18c47be7f5cf9280bc58f586 100644 (file)
@@ -144,6 +144,14 @@ namespace Internal.TypeSystem
             }
         }
 
+        public override IEnumerable<MethodDesc> GetVirtualMethods()
+        {
+            foreach (var typicalMethodDef in _typeDef.GetVirtualMethods())
+            {
+                yield return _typeDef.Context.GetMethodForInstantiatedType(typicalMethodDef, this);
+            }
+        }
+
         // TODO: Substitutions, generics, modopts, ...
         public override MethodDesc GetMethod(string name, MethodSignature signature, Instantiation substitution)
         {
index a3af0aa5faa272119af3deffbc51350a39ea08d1..5a33ab437a5f878c66e6f081bf4239ed5516f9b4 100644 (file)
@@ -330,11 +330,8 @@ namespace Internal.TypeSystem
             MethodSignature sig = targetMethod.Signature;
 
             MethodDesc implMethod = null;
-            foreach (MethodDesc candidate in currentType.GetAllMethods())
+            foreach (MethodDesc candidate in currentType.GetAllVirtualMethods())
             {
-                if (!candidate.IsVirtual)
-                    continue;
-
                 if (candidate.Name == name)
                 {
                     if (candidate.Signature.Equals(sig))
@@ -810,11 +807,8 @@ namespace Internal.TypeSystem
             {
                 do
                 {
-                    foreach (MethodDesc m in type.GetAllMethods())
+                    foreach (MethodDesc m in type.GetAllVirtualMethods())
                     {
-                        if (!m.IsVirtual)
-                            continue;
-
                         MethodDesc possibleVirtual = FindSlotDefiningMethodForVirtualMethod(m);
                         if (!alreadyEnumerated.Contains(possibleVirtual))
                         {
index 489fa6d1e3d9fabd86dc3c288b6a34427ce56422..a4f9e6ac985c5f3d941bda1171aa5883843c2bf0 100644 (file)
   <data name="BadImageFormatSpecific" xml:space="preserve">
     <value>The format of a DLL or executable being loaded is invalid with {0}</value>
   </data>
+  <data name="MarshalDirectiveGeneric" xml:space="preserve">
+    <value>Marshaling directives are invalid</value>
+  </data>
 </root>
index 90c02f6ad3aab08099bba67436787368015ef312..4e31950b40e99b65edb37cef361171a05c930cf3 100644 (file)
@@ -65,6 +65,12 @@ namespace Internal.TypeSystem
             throw new TypeSystemException.BadImageFormatException(message);
         }
 
+        [System.Diagnostics.DebuggerHidden]
+        public static void ThrowMarshalDirectiveException()
+        {
+            throw new TypeSystemException.MarshalDirectiveException(ExceptionStringID.MarshalDirectiveGeneric);
+        }
+
         private static partial class Format
         {
             public static string OwningModule(TypeDesc type)
index b60e0161c81f23b49997fd24a0d0b6c0c59818f4..51cf7291cdd74879b6b526ff1402351c1bc9f71e 100644 (file)
@@ -510,6 +510,16 @@ namespace Internal.TypeSystem
             return MethodDesc.EmptyMethods;
         }
 
+        /// <summary>
+        /// Gets a subset of methods returned by <see cref="GetMethods"/> that are virtual.
+        /// </summary>
+        public virtual IEnumerable<MethodDesc> GetVirtualMethods()
+        {
+            foreach (MethodDesc method in GetMethods())
+                if (method.IsVirtual)
+                    yield return method;
+        }
+
         /// <summary>
         /// Gets a named method on the type. This method only looks at methods defined
         /// in type's metadata. The <paramref name="signature"/> parameter can be null.
index 21c17d47d991908a0b35116845a00350cb8fc681..fcb47f42d3c92de5a9c171e2b8ccfba86718b85c 100644 (file)
@@ -677,6 +677,11 @@ namespace Internal.TypeSystem
             return type.GetMethods();
         }
 
+        protected internal virtual IEnumerable<MethodDesc> GetAllVirtualMethods(TypeDesc type)
+        {
+            return type.GetVirtualMethods();
+        }
+
         /// <summary>
         /// Abstraction to allow the type system context to affect the field layout
         /// algorithm used by types to lay themselves out.
index 598f0f602748e7a14fed079514c642f267f473c1..39015e807d94c89e4c99d6ddf2d5b0d567ec7eb3 100644 (file)
@@ -162,5 +162,13 @@ namespace Internal.TypeSystem
 
             }
         }
+
+        public class MarshalDirectiveException : TypeSystemException
+        {
+            internal MarshalDirectiveException(ExceptionStringID id)
+                : base(id)
+            {
+            }
+        }
     }
 }
index 76bb19921aaeabfc7fa18a7dbfc8634c924da775..2442f04fee89631606e09e13ee09668be8c69aa6 100644 (file)
@@ -261,6 +261,14 @@ namespace Internal.TypeSystem
             return type.Context.GetAllMethods(type);
         }
 
+        /// <summary>
+        /// Retrieves all virtual methods on a type, including the ones injected by the type system context.
+        /// </summary>
+        public static IEnumerable<MethodDesc> GetAllVirtualMethods(this TypeDesc type)
+        {
+            return type.Context.GetAllVirtualMethods(type);
+        }
+
         public static IEnumerable<MethodDesc> EnumAllVirtualSlots(this TypeDesc type)
         {
             return type.Context.GetVirtualMethodAlgorithmForType(type).ComputeAllVirtualSlots(type);
index e353a592df40f86a089d9bb3ec52e26dd2b6bb0b..ea55c07ad767bca0d6f565263276aa1c1e2dc2e3 100644 (file)
@@ -202,9 +202,15 @@ namespace Internal.TypeSystem
                 }
 
                 if (assemblyName.StartsWith("System.Private", StringComparison.Ordinal))
-                    assemblyName = "S.P" + assemblyName.Substring(14);
+                {
+                    sb.Append("S.P");
+                    sb.Append(assemblyName, 14, assemblyName.Length - 14);
+                }
+                else
+                {
+                    sb.Append(assemblyName);
+                }
 
-                sb.Append(assemblyName);
                 sb.Append(']');
             }
         }
index 8075ef7e4b6f8f15c5ea3d8252dd882618cfd055..073cb7a4fdfb2b9d509acdbcf25abcb8573f4793 100644 (file)
@@ -306,7 +306,18 @@ namespace Internal.TypeSystem.Ecma
         {
             foreach (var handle in _typeDefinition.GetMethods())
             {
-                yield return (MethodDesc)_module.GetObject(handle);
+                yield return (EcmaMethod)_module.GetObject(handle);
+            }
+        }
+
+        public override IEnumerable<MethodDesc> GetVirtualMethods()
+        {
+            MetadataReader reader = _module.MetadataReader;
+            foreach (var handle in _typeDefinition.GetMethods())
+            {
+                MethodDefinition methodDef = reader.GetMethodDefinition(handle);
+                if ((methodDef.Attributes & MethodAttributes.Virtual) != 0)
+                    yield return (EcmaMethod)_module.GetObject(handle);
             }
         }
 
@@ -319,7 +330,7 @@ namespace Internal.TypeSystem.Ecma
             {
                 if (stringComparer.Equals(metadataReader.GetMethodDefinition(handle).Name, name))
                 {
-                    MethodDesc method = (MethodDesc)_module.GetObject(handle);
+                    var method = (EcmaMethod)_module.GetObject(handle);
                     if (signature == null || signature.Equals(method.Signature.ApplySubstitution(substitution)))
                         return method;
                 }
@@ -339,7 +350,7 @@ namespace Internal.TypeSystem.Ecma
                 if (methodDefinition.Attributes.IsRuntimeSpecialName() &&
                     stringComparer.Equals(methodDefinition.Name, ".cctor"))
                 {
-                    MethodDesc method = (MethodDesc)_module.GetObject(handle);
+                    var method = (EcmaMethod)_module.GetObject(handle);
                     return method;
                 }
             }
@@ -362,7 +373,7 @@ namespace Internal.TypeSystem.Ecma
                 if (attributes.IsRuntimeSpecialName() && attributes.IsPublic()
                     && stringComparer.Equals(methodDefinition.Name, ".ctor"))
                 {
-                    MethodDesc method = (MethodDesc)_module.GetObject(handle);
+                    var method = (EcmaMethod)_module.GetObject(handle);
                     if (method.Signature.Length != 0)
                         continue;
 
@@ -435,7 +446,7 @@ namespace Internal.TypeSystem.Ecma
         {
             foreach (var handle in _typeDefinition.GetNestedTypes())
             {
-                yield return (MetadataType)_module.GetObject(handle);
+                yield return (EcmaType)_module.GetObject(handle);
             }
         }
 
@@ -460,7 +471,7 @@ namespace Internal.TypeSystem.Ecma
                 }
 
                 if (nameMatched)
-                    return (MetadataType)_module.GetObject(handle);
+                    return (EcmaType)_module.GetObject(handle);
             }
 
             return null;
@@ -527,7 +538,7 @@ namespace Internal.TypeSystem.Ecma
                     // Note: GetOffset() returns -1 when offset was not set in the metadata
                     int specifiedOffset = fieldDefinition.GetOffset();
                     result.Offsets[index] =
-                        new FieldAndOffset((FieldDesc)_module.GetObject(handle), specifiedOffset == -1 ? FieldAndOffset.InvalidOffset : new LayoutInt(specifiedOffset));
+                        new FieldAndOffset((EcmaField)_module.GetObject(handle), specifiedOffset == -1 ? FieldAndOffset.InvalidOffset : new LayoutInt(specifiedOffset));
 
                     index++;
                 }
index b7aacf68eb85d49284b35dba873c448ef186362b..5d8d4fd0f4c2b5f94eb64930be8fe77015c86a95 100644 (file)
@@ -123,12 +123,25 @@ namespace Internal.TypeSystem.Ecma
 
             var sequencePoints = debugInformation.GetSequencePoints();
 
+            DocumentHandle previousDocumentHandle = default;
+            string previousDocumentUrl = null;
+
             foreach (var sequencePoint in sequencePoints)
             {
-                if (sequencePoint.StartLine == 0xFEEFEE)
+                if (sequencePoint.StartLine == SequencePoint.HiddenLine)
                     continue;
 
-                var url = _reader.GetString(_reader.GetDocument(sequencePoint.Document).Name);
+                string url;
+                if (sequencePoint.Document == previousDocumentHandle)
+                {
+                    url = previousDocumentUrl;
+                }
+                else
+                {
+                    url = _reader.GetString(_reader.GetDocument(sequencePoint.Document).Name);
+                    previousDocumentHandle = sequencePoint.Document;
+                    previousDocumentUrl = url;
+                }
 
                 yield return new ILSequencePoint(sequencePoint.Offset, url, sequencePoint.StartLine);
             }
index 1989b6514b86af55a456b46faa3560a425a9fe5a..64ba412f6afbcfccf25332394d655c623c1da354 100644 (file)
@@ -63,6 +63,9 @@ namespace Internal.TypeSystem.Interop
                 case MarshallerKind.CBool:
                         return context.GetWellKnownType(WellKnownType.Byte);
 
+                case MarshallerKind.VariantBool:
+                    return context.GetWellKnownType(WellKnownType.Int16);
+
                 case MarshallerKind.Enum:
                 case MarshallerKind.BlittableStruct:
                 case MarshallerKind.Decimal:
@@ -162,6 +165,14 @@ namespace Internal.TypeSystem.Interop
                 case MarshallerKind.ComInterface:
                     return context.GetWellKnownType(WellKnownType.IntPtr);
 
+#if !READYTORUN
+                case MarshallerKind.Variant:
+                    return InteropTypes.GetVariant(context);
+#endif
+
+                case MarshallerKind.OleCurrency:
+                    return context.GetWellKnownType(WellKnownType.Int64);
+
                 case MarshallerKind.Unknown:
                 default:
                     throw new NotSupportedException();
@@ -254,6 +265,9 @@ namespace Internal.TypeSystem.Interop
                             case NativeTypeKind.I1:
                                 return MarshallerKind.CBool;
 
+                            case NativeTypeKind.VariantBool:
+                                return MarshallerKind.VariantBool;
+
                             default:
                                 return MarshallerKind.Invalid;
                         }
@@ -355,6 +369,8 @@ namespace Internal.TypeSystem.Interop
                         return MarshallerKind.Decimal;
                     else if (nativeType == NativeTypeKind.LPStruct && !isField)
                         return MarshallerKind.BlittableStructPtr;
+                    else if (nativeType == NativeTypeKind.Currency)
+                        return MarshallerKind.OleCurrency;
                     else
                         return MarshallerKind.Invalid;
                 }
@@ -434,9 +450,6 @@ namespace Internal.TypeSystem.Interop
                 {
                     case NativeTypeKind.Array:
                         {
-                            if (isField || isReturn)
-                                return MarshallerKind.Invalid;
-
                             var arrayType = (ArrayType)type;
 
                             elementMarshallerKind = GetArrayElementMarshallerKind(
@@ -569,7 +582,7 @@ namespace Internal.TypeSystem.Interop
                     || nativeType == NativeTypeKind.IUnknown)
                     return MarshallerKind.ComInterface;
                 else
-                    return MarshallerKind.Invalid;
+                    return MarshallerKind.Variant;
             }
             else if (InteropTypes.IsStringBuilder(context, type))
             {
@@ -794,6 +807,11 @@ namespace Internal.TypeSystem.Interop
                         return MarshallerKind.UnicodeString;
                     case NativeTypeKind.LPUTF8Str:
                         return MarshallerKind.UTF8String;
+                    case NativeTypeKind.BStr:
+                    case NativeTypeKind.TBStr:
+                        return MarshallerKind.BSTRString;
+                    case NativeTypeKind.AnsiBStr:
+                        return MarshallerKind.AnsiBSTRString;
                     default:
                         return MarshallerKind.Invalid;
                 }
index d9d23c55836642810c7a363313163ec257fc15f0..46c53157b465a2596254694e7e88cebd9df7dfa2 100644 (file)
@@ -19,6 +19,7 @@ namespace Internal.TypeSystem.Interop
         BlittableArray,
         Bool,   // 4 byte bool
         CBool,  // 1 byte bool
+        VariantBool,  // Variant bool
         Enum,
         AnsiChar,  // Marshal char (Unicode 16bits) for byte (Ansi 8bits)
         UnicodeChar,
@@ -43,6 +44,7 @@ namespace Internal.TypeSystem.Interop
         Object,
         OleDateTime,
         Decimal,
+        OleCurrency,
         Guid,
         Struct,
         BlittableStruct,
@@ -152,7 +154,7 @@ namespace Internal.TypeSystem.Interop
         public bool Return;
         public bool IsManagedByRef;                     // Whether managed argument is passed by ref
         public bool IsNativeByRef;                      // Whether native argument is passed by byref
-                                                        // There are special cases (such as LpStruct, and class) that 
+                                                        // There are special cases (such as LpStruct, and class) that
                                                         // isNativeByRef != IsManagedByRef
         public MarshalDirection MarshalDirection;
         protected PInvokeILCodeStreams _ilCodeStreams;
@@ -245,7 +247,7 @@ namespace Internal.TypeSystem.Interop
                         break;
                     default:
                         // Storing by-ref arg/local is not supported because StInd require
-                        // address to be pushed first. Instead we need to introduce a non-byref 
+                        // address to be pushed first. Instead we need to introduce a non-byref
                         // local and propagate value as needed for by-ref arguments
                         Debug.Assert(false);
                         break;
@@ -333,7 +335,7 @@ namespace Internal.TypeSystem.Interop
             //
             if (isOut)
             {
-                // Passing as [Out] by ref is always valid. 
+                // Passing as [Out] by ref is always valid.
                 if (!marshaller.IsManagedByRef)
                 {
                     // Ignore [Out] for ValueType, string and pointers
@@ -634,7 +636,7 @@ namespace Internal.TypeSystem.Interop
 
         /// <summary>
         /// Propagate by-ref arg to corresponding local
-        /// We can't load value + ldarg + ldind in the expected order, so 
+        /// We can't load value + ldarg + ldind in the expected order, so
         /// we had to use a non-by-ref local and manually propagate the value
         /// </summary>
         protected void PropagateFromByRefArg(ILCodeStream stream, Home home)
@@ -646,7 +648,7 @@ namespace Internal.TypeSystem.Interop
 
         /// <summary>
         /// Propagate local to corresponding by-ref arg
-        /// We can't load value + ldarg + ldind in the expected order, so 
+        /// We can't load value + ldarg + ldind in the expected order, so
         /// we had to use a non-by-ref local and manually propagate the value
         /// </summary>
         protected void PropagateToByRefArg(ILCodeStream stream, Home home)
@@ -838,7 +840,7 @@ namespace Internal.TypeSystem.Interop
             SetupArgumentsForFieldMarshalling();
             //
             // For field marshalling we expect the value of the field is already loaded
-            // in the stack. 
+            // in the stack.
             //
             StoreManagedValue(marshallingCodeStream);
 
@@ -980,6 +982,11 @@ namespace Internal.TypeSystem.Interop
             }
         }
 
+        protected override void SetupArgumentsForFieldMarshalling()
+        {
+            ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, ManagedType);
+        }
+
         protected Marshaller GetElementMarshaller(MarshalDirection direction)
         {
             if (_elementMarshaller == null)
@@ -1038,7 +1045,7 @@ namespace Internal.TypeSystem.Interop
 
                     if (index < 0 || index >= Marshallers.Length - 1)
                     {
-                        throw new InvalidProgramException("Invalid SizeParamIndex, must be between 0 and parameter count");
+                        ThrowHelper.ThrowMarshalDirectiveException();
                     }
 
                     //zero-th index is for return type
@@ -1058,7 +1065,8 @@ namespace Internal.TypeSystem.Interop
                         case TypeFlags.UIntPtr:
                             break;
                         default:
-                            throw new InvalidProgramException("Invalid SizeParamIndex, parameter must be  of type int/uint");
+                            ThrowHelper.ThrowMarshalDirectiveException();
+                            break;
                     }
 
                     // @TODO - We can use LoadManagedValue, but that requires byref arg propagation happen in a special setup stream
@@ -1347,7 +1355,7 @@ namespace Internal.TypeSystem.Interop
             // Check for null array
             LoadManagedValue(codeStream);
             codeStream.Emit(ILOpcode.brfalse, lNullArray);
-            
+
             if (IsManagedByRef)
             {
                 base.AllocManagedToNative(codeStream);
@@ -1405,13 +1413,38 @@ namespace Internal.TypeSystem.Interop
 
     class BooleanMarshaller : Marshaller
     {
+        private int _trueValue;
+        public BooleanMarshaller(int trueValue = 1)
+        {
+            _trueValue = trueValue;
+        }
+
         protected override void AllocAndTransformManagedToNative(ILCodeStream codeStream)
         {
+            ILEmitter emitter = _ilCodeStreams.Emitter;
+            ILCodeLabel pLoadFalseLabel = emitter.NewCodeLabel();
+            ILCodeLabel pDoneLabel = emitter.NewCodeLabel();
+
             LoadManagedValue(codeStream);
-            codeStream.EmitLdc(0);
-            codeStream.Emit(ILOpcode.ceq);
-            codeStream.EmitLdc(0);
-            codeStream.Emit(ILOpcode.ceq);
+            if (_trueValue == 1)
+            {
+                codeStream.EmitLdc(0);
+                codeStream.Emit(ILOpcode.ceq);
+                codeStream.EmitLdc(0);
+                codeStream.Emit(ILOpcode.ceq);
+            }
+            else
+            {
+                codeStream.Emit(ILOpcode.brfalse, pLoadFalseLabel);
+                codeStream.EmitLdc(_trueValue);
+                codeStream.Emit(ILOpcode.br, pDoneLabel);
+
+                codeStream.EmitLabel(pLoadFalseLabel);
+                codeStream.EmitLdc(0);
+
+                codeStream.EmitLabel(pDoneLabel);
+            }
+
             StoreNativeValue(codeStream);
         }
 
@@ -1763,7 +1796,7 @@ namespace Internal.TypeSystem.Interop
                 cleanupCodeStream.Emit(ILOpcode.brfalse, lNotAddrefed);
                 LoadManagedValue(cleanupCodeStream);
                 cleanupCodeStream.Emit(ILOpcode.call, emitter.NewToken(
-                    safeHandleType.GetKnownMethod("DangerousRelease", 
+                    safeHandleType.GetKnownMethod("DangerousRelease",
                         new MethodSignature(0, 0, Context.GetWellKnownType(WellKnownType.Void), TypeDesc.EmptyTypes))));
                 cleanupCodeStream.EmitLabel(lNotAddrefed);
             }
@@ -1774,7 +1807,7 @@ namespace Internal.TypeSystem.Interop
                 //    must allocate this before the native call to avoid a failure point when we already have a native resource
                 //    allocated. We must allocate a new SafeHandle even if we have one on input since both input and output native
                 //    handles need to be tracked and released by a SafeHandle.
-                // 2) Initialize a local IntPtr that will be passed to the native call. 
+                // 2) Initialize a local IntPtr that will be passed to the native call.
                 // 3) After the native call, the new handle value is written into the output SafeHandle and that SafeHandle
                 //    is propagated back to the caller.
                 var vSafeHandle = emitter.NewLocal(ManagedType);
@@ -1891,7 +1924,7 @@ namespace Internal.TypeSystem.Interop
                 ))));
 #else
             codeStream.Emit(ILOpcode.ldtoken, _ilCodeStreams.Emitter.NewToken(ManagedType));
-            
+
             codeStream.Emit(ILOpcode.call, _ilCodeStreams.Emitter.NewToken(
                 InteropTypes.GetPInvokeMarshal(Context).GetKnownMethod("GetDelegateForFunctionPointer",
                 new MethodSignature(MethodSignatureFlags.Static, 0, Context.GetWellKnownType(WellKnownType.MulticastDelegate).BaseType,
index 05c95826e265bd33023faa2d3d810446901729c9..26b5312c4b8f8b7c0e02d6b639c24bc49efd4662 100644 (file)
@@ -19,6 +19,7 @@ namespace Internal.TypeSystem
         U8 = 0xa,
         R4 = 0xb,
         R8 = 0xc,
+        Currency = 0xf,
         BStr = 0x13,
         LPStr = 0x14,
         LPWStr = 0x15,
@@ -33,6 +34,7 @@ namespace Internal.TypeSystem
         SysUInt = 0x20,
         AnsiBStr = 0x23,
         TBStr = 0x24,
+        VariantBool = 0x25,
         Func = 0x26,
         AsAny = 0x28,
         Array = 0x2a,
index e651989e182ff7aab602afddee31c50490f718c6..df7dbd13dde94090bf52d9206bda214f0038579d 100644 (file)
@@ -114,6 +114,14 @@ namespace Internal.TypeSystem
             }
         }
 
+        public override IEnumerable<MethodDesc> GetVirtualMethods()
+        {
+            foreach (var method in _rawCanonType.GetVirtualMethods())
+            {
+                yield return Context.GetMethodForRuntimeDeterminedType(method.GetTypicalMethodDefinition(), this);
+            }
+        }
+
         public override MethodDesc GetMethod(string name, MethodSignature signature, Instantiation substitution)
         {
             MethodDesc method = _rawCanonType.GetMethod(name, signature, substitution);
index 9fc3b9bf7d0d0b844dbd79b8430f3d2d76e56ad1..46aa71cc6ac94f60aba4eb8fd1417277fd167b72 100644 (file)
@@ -153,6 +153,21 @@ namespace TypeSystemTests
                 foreach (var m in mdType.GetMethods())
                     yield return m;
             }
+
+            protected override IEnumerable<MethodDesc> GetAllVirtualMethods(TypeDesc type)
+            {
+                MetadataType mdType = type as MetadataType;
+
+                if (mdType.Name == "StructWithNoEqualsAndGetHashCode"
+                    || mdType.Name == "ClassWithInjectedEqualsAndGetHashCode")
+                {
+                    yield return GetEqualsMethod(type);
+                    yield return GetGetHashCodeMethod(type);
+                }
+
+                foreach (var m in mdType.GetVirtualMethods())
+                    yield return m;
+            }
         }
 
         private partial class SyntheticMethod : MethodDesc
index cc2d1d16a1099733bc376c5565f096fc0c3cb16f..5f19d27dfc057d6be2625a9b4ea738259f35dcd9 100644 (file)
@@ -3,6 +3,7 @@
 
 using System.Text;
 using System.Reflection;
+using System.Runtime.CompilerServices;
 
 namespace System.Diagnostics
 {
@@ -57,6 +58,7 @@ namespace System.Diagnostics
         /// <summary>
         /// Constructs a StackFrame corresponding to the active stack frame.
         /// </summary>
+        [MethodImplAttribute(MethodImplOptions.NoInlining)]
         public StackFrame()
         {
             InitMembers();
@@ -66,6 +68,7 @@ namespace System.Diagnostics
         /// <summary>
         /// Constructs a StackFrame corresponding to the active stack frame.
         /// </summary>
+        [MethodImplAttribute(MethodImplOptions.NoInlining)]
         public StackFrame(bool needFileInfo)
         {
             InitMembers();
@@ -75,6 +78,7 @@ namespace System.Diagnostics
         /// <summary>
         /// Constructs a StackFrame corresponding to a calling stack frame.
         /// </summary>
+        [MethodImplAttribute(MethodImplOptions.NoInlining)]
         public StackFrame(int skipFrames)
         {
             InitMembers();
@@ -84,6 +88,7 @@ namespace System.Diagnostics
         /// <summary>
         /// Constructs a StackFrame corresponding to a calling stack frame.
         /// </summary>
+        [MethodImplAttribute(MethodImplOptions.NoInlining)]
         public StackFrame(int skipFrames, bool needFileInfo)
         {
             InitMembers();
@@ -95,6 +100,7 @@ namespace System.Diagnostics
         /// name and line number.  Use when you don't want to use the
         /// debugger's line mapping logic.
         /// </summary>
+        [MethodImplAttribute(MethodImplOptions.NoInlining)]
         public StackFrame(string? fileName, int lineNumber)
         {
             InitMembers();
@@ -109,9 +115,14 @@ namespace System.Diagnostics
         /// name, line number and column number.  Use when you don't want to
         /// use the debugger's line mapping logic.
         /// </summary>
+        [MethodImplAttribute(MethodImplOptions.NoInlining)]
         public StackFrame(string? fileName, int lineNumber, int colNumber)
-            : this(fileName, lineNumber)
         {
+            InitMembers();
+
+            BuildStackFrame(StackTrace.METHODS_TO_SKIP, false);
+            _fileName = fileName;
+            _lineNumber = lineNumber;
             _columnNumber = colNumber;
         }
 
index f8e46b08a9c75bfc8b90bffc87b21c9abb7e1b6f..50d873d90b5e90cab3011e26c7ce595b59a433bc 100644 (file)
@@ -30,6 +30,7 @@ namespace System.Diagnostics
         /// <summary>
         /// Constructs a stack trace from the current location.
         /// </summary>
+        [MethodImplAttribute(MethodImplOptions.NoInlining)]
         public StackTrace()
         {
             InitializeForCurrentThread(METHODS_TO_SKIP, false);
@@ -38,6 +39,7 @@ namespace System.Diagnostics
         /// <summary>
         /// Constructs a stack trace from the current location.
         /// </summary>
+        [MethodImplAttribute(MethodImplOptions.NoInlining)]
         public StackTrace(bool fNeedFileInfo)
         {
             InitializeForCurrentThread(METHODS_TO_SKIP, fNeedFileInfo);
@@ -47,6 +49,7 @@ namespace System.Diagnostics
         /// Constructs a stack trace from the current location, in a caller's
         /// frame
         /// </summary>
+        [MethodImplAttribute(MethodImplOptions.NoInlining)]
         public StackTrace(int skipFrames)
         {
             if (skipFrames < 0)
@@ -60,6 +63,7 @@ namespace System.Diagnostics
         /// Constructs a stack trace from the current location, in a caller's
         /// frame
         /// </summary>
+        [MethodImplAttribute(MethodImplOptions.NoInlining)]
         public StackTrace(int skipFrames, bool fNeedFileInfo)
         {
             if (skipFrames < 0)
index 2a8ccd166eaf1edbea23472b6d71bf057f49aabd..0352277260b1777533abebd5edd3636fac76886d 100644 (file)
@@ -10,6 +10,18 @@ namespace System.Text.Json.Serialization.Metadata
 {
     internal sealed class ReflectionMemberAccessor : MemberAccessor
     {
+        private class ConstructorContext
+        {
+            [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]
+            private readonly Type _type;
+
+            public ConstructorContext([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type)
+                => _type = type;
+
+            public object? CreateInstance()
+                => Activator.CreateInstance(_type, nonPublic: false);
+        }
+
         public override JsonTypeInfo.ConstructorDelegate? CreateConstructor(
             [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type)
         {
@@ -26,7 +38,7 @@ namespace System.Text.Json.Serialization.Metadata
                 return null;
             }
 
-            return () => Activator.CreateInstance(type, nonPublic: false);
+            return new ConstructorContext(type).CreateInstance;
         }
 
         public override JsonTypeInfo.ParameterizedConstructorDelegate<T>? CreateParameterizedConstructor<T>(ConstructorInfo constructor)