Add IsDynamicCodeSupported Feature Switch (#80246)
authorEric Erhardt <eric.erhardt@microsoft.com>
Mon, 9 Jan 2023 20:42:00 +0000 (14:42 -0600)
committerGitHub <noreply@github.com>
Mon, 9 Jan 2023 20:42:00 +0000 (14:42 -0600)
* Add IsDynamicCodeSupported Feature Switch

This adds the ability to disable reflection emit for testing. It also allows for applications/libraries to simulate NativeAOT behavior (like switching on RuntimeFeature.IsDynamicCodeSupported) without actually publishing for NativeAOT.

Fix #39806

* Add IsDynamicCodeSupported feature switch support for Mono

* Remove featuredefault for IsDynamicCodeSupported so it isn't substituted during CoreLib's build.

* Add Intrinsic attribute back for Mono

26 files changed:
src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj
src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.xml
src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs
src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs
src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/SignatureHelper.cs
src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.CoreCLR.cs [deleted file]
src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs
src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs
src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.NonNativeAot.cs [new file with mode: 0644]
src/libraries/System.Reflection.Emit.ILGeneration/tests/CustomAttributeBuilderTests.cs
src/libraries/System.Reflection.Emit.ILGeneration/tests/SignatureHelper/SignatureHelperDynamicCodeNotSupported.cs [new file with mode: 0644]
src/libraries/System.Reflection.Emit.ILGeneration/tests/System.Reflection.Emit.ILGeneration.Tests.csproj
src/libraries/System.Reflection.Emit.Lightweight/tests/DynamicMethodCtor.cs
src/libraries/System.Reflection.Emit.Lightweight/tests/System.Reflection.Emit.Lightweight.Tests.csproj
src/libraries/System.Reflection.Emit/tests/AssemblyBuilderTests.cs
src/libraries/System.Reflection.Emit/tests/System.Reflection.Emit.Tests.csproj
src/libraries/System.Runtime/tests/System/Runtime/CompilerServices/RuntimeFeatureTests.cs
src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj
src/mono/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.Mono.cs
src/mono/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.Mono.cs
src/mono/System.Private.CoreLib/src/System/Reflection/Emit/SignatureHelper.cs
src/mono/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.Mono.cs [deleted file]
src/mono/mono/mini/interp/transform.c
src/mono/mono/mini/intrinsics.c
src/tests/issues.targets

index 8e55e21..b432030 100644 (file)
     <Compile Include="$(BclSourcesRoot)\System\Resources\ManifestBasedResourceGroveler.CoreCLR.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\CastHelpers.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\ICastableHelpers.cs" />
-    <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\RuntimeFeature.CoreCLR.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\RuntimeHelpers.CoreCLR.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Runtime\ControlledExecution.CoreCLR.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Runtime\DependentHandle.cs" />
index 227fdc6..7453ebc 100644 (file)
@@ -1,5 +1,13 @@
 <linker>
   <assembly fullname="System.Private.CoreLib">
+    <type fullname="System.Runtime.CompilerServices.RuntimeFeature" feature="System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported" featurevalue="true">
+      <method signature="System.Boolean get_IsDynamicCodeCompiled()" body="stub" value="true" />
+      <method signature="System.Boolean get_IsDynamicCodeSupported()" body="stub" value="true" />
+    </type>
+    <type fullname="System.Runtime.CompilerServices.RuntimeFeature" feature="System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported" featurevalue="false">
+      <method signature="System.Boolean get_IsDynamicCodeCompiled()" body="stub" value="false" />
+      <method signature="System.Boolean get_IsDynamicCodeSupported()" body="stub" value="false" />
+    </type>
     <type fullname="System.StartupHookProvider" feature="System.StartupHookProvider.IsSupported" featurevalue="false">
       <method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
     </type>
index e3f45b4..ee01fd5 100644 (file)
@@ -56,6 +56,8 @@ namespace System.Reflection.Emit
                 throw new InvalidOperationException();
             }
 
+            EnsureDynamicCodeSupported();
+
             _access = access;
 
             _internalAssembly = CreateDynamicAssembly(assemblyLoadContext ?? AssemblyLoadContext.GetLoadContext(callingAssembly)!, name, access);
index d8a31cf..ad84b7e 100644 (file)
@@ -57,6 +57,8 @@ namespace System.Reflection.Emit
             ArgumentNullException.ThrowIfNull(namedFields);
             ArgumentNullException.ThrowIfNull(fieldValues);
 
+            AssemblyBuilder.EnsureDynamicCodeSupported();
+
 #pragma warning disable CA2208 // Instantiate argument exceptions correctly, combination of arguments used
             if (namedProperties.Length != propertyValues.Length)
                 throw new ArgumentException(SR.Arg_ArrayLengthsDiffer, "namedProperties, propertyValues");
index 5106ff7..fe5506f 100644 (file)
@@ -223,6 +223,8 @@ namespace System.Reflection.Emit
 
             if (m_module == null && mod != null)
                 throw new ArgumentException(SR.NotSupported_MustBeModuleBuilder);
+
+            AssemblyBuilder.EnsureDynamicCodeSupported();
         }
 
         [MemberNotNull(nameof(m_signature))]
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.CoreCLR.cs
deleted file mode 100644 (file)
index 2f98784..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace System.Runtime.CompilerServices
-{
-    public static partial class RuntimeFeature
-    {
-        public static bool IsDynamicCodeSupported => true;
-        public static bool IsDynamicCodeCompiled => true;
-    }
-}
index d048995..93ee89a 100644 (file)
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\RequiredMemberAttribute.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\RuntimeCompatibilityAttribute.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\RuntimeFeature.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\RuntimeFeature.NonNativeAot.cs" Condition="'$(FeatureNativeAot)' != 'true'" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\RuntimeHelpers.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\RuntimeWrappedException.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\SkipLocalsInitAttribute.cs" />
index 2bfa126..b0345a3 100644 (file)
@@ -3,6 +3,7 @@
 
 using System.Diagnostics.CodeAnalysis;
 using System.IO;
+using System.Runtime.CompilerServices;
 
 namespace System.Reflection.Emit
 {
@@ -38,5 +39,16 @@ namespace System.Reflection.Emit
 
         public override Stream? GetManifestResourceStream(Type type, string name) =>
             throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
+
+        internal static void EnsureDynamicCodeSupported()
+        {
+            if (!RuntimeFeature.IsDynamicCodeSupported)
+            {
+                ThrowDynamicCodeNotSupported();
+            }
+        }
+
+        private static void ThrowDynamicCodeNotSupported() =>
+            throw new PlatformNotSupportedException(SR.PlatformNotSupported_ReflectionEmit);
     }
 }
index ba91f5e..9708590 100644 (file)
@@ -223,6 +223,8 @@ namespace System.Reflection.Emit
         {
             ArgumentNullException.ThrowIfNull(name);
 
+            AssemblyBuilder.EnsureDynamicCodeSupported();
+
             if (attributes != (MethodAttributes.Static | MethodAttributes.Public) || callingConvention != CallingConventions.Standard)
                 throw new NotSupportedException(SR.NotSupported_DynamicMethodFlags);
 
diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.NonNativeAot.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.NonNativeAot.cs
new file mode 100644 (file)
index 0000000..1ae0005
--- /dev/null
@@ -0,0 +1,24 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace System.Runtime.CompilerServices
+{
+    public static partial class RuntimeFeature
+    {
+        public static bool IsDynamicCodeSupported
+        {
+#if MONO
+            [Intrinsic]  // the Mono AOT compiler will change this flag to false for FullAOT scenarios, otherwise this code is used
+#endif
+            get;
+        } = AppContext.TryGetSwitch("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", out bool isDynamicCodeSupported) ? isDynamicCodeSupported : true;
+
+        public static bool IsDynamicCodeCompiled
+        {
+#if MONO
+            [Intrinsic]  // the Mono AOT compiler and Interpreter will change this flag to false for FullAOT and interpreted scenarios, otherwise this code is used
+#endif
+            get => IsDynamicCodeSupported;
+        }
+    }
+}
index b349b17..af56498 100644 (file)
@@ -5,6 +5,7 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using Microsoft.DotNet.RemoteExecutor;
 using Xunit;
 
 namespace System.Reflection.Emit.Tests
@@ -1069,6 +1070,28 @@ namespace System.Reflection.Emit.Tests
             AssertExtensions.Throws<ArgumentException>(paramName, () => new CustomAttributeBuilder(con, new object[0], namedProperties, propertyValues, new FieldInfo[0], new object[0]));
         }
 
+        [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
+        public static void ThrowsWhenDynamicCodeNotSupported()
+        {
+            RemoteInvokeOptions options = new RemoteInvokeOptions();
+            options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", false.ToString());
+
+            using RemoteInvokeHandle remoteHandle = RemoteExecutor.Invoke(static () =>
+            {
+                ConstructorInfo con = typeof(TestAttribute).GetConstructor(new Type[0]);
+                object[] constructorArgs = new object[0];
+                PropertyInfo[] namedProperties = Helpers.GetProperties(typeof(TestAttribute), nameof(TestAttribute.ObjectProperty));
+                object[] propertyValues = new object[] { new int[0, 0] };
+                FieldInfo[] namedFields = new FieldInfo[0];
+                object[] fieldValues = new object[0];
+
+                Assert.Throws<PlatformNotSupportedException>(() => new CustomAttributeBuilder(con, constructorArgs));
+                Assert.Throws<PlatformNotSupportedException>(() => new CustomAttributeBuilder(con, constructorArgs, namedFields, fieldValues));
+                Assert.Throws<PlatformNotSupportedException>(() => new CustomAttributeBuilder(con, constructorArgs, namedProperties, propertyValues));
+                Assert.Throws<PlatformNotSupportedException>(() => new CustomAttributeBuilder(con, constructorArgs, namedProperties, propertyValues, namedFields, fieldValues));
+            }, options);
+        }
+
         private static Type CreateEnum(Type underlyingType, params object[] literalValues)
         {
             ModuleBuilder module = Helpers.DynamicModule();
diff --git a/src/libraries/System.Reflection.Emit.ILGeneration/tests/SignatureHelper/SignatureHelperDynamicCodeNotSupported.cs b/src/libraries/System.Reflection.Emit.ILGeneration/tests/SignatureHelper/SignatureHelperDynamicCodeNotSupported.cs
new file mode 100644 (file)
index 0000000..f9eb8f2
--- /dev/null
@@ -0,0 +1,31 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.DotNet.RemoteExecutor;
+using Xunit;
+
+namespace System.Reflection.Emit.Tests
+{
+    public class SignatureHelperDynamicCodeNotSupported
+    {
+        [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
+        public static void ThrowsWhenDynamicCodeNotSupported()
+        {
+            RemoteInvokeOptions options = new RemoteInvokeOptions();
+            options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", false.ToString());
+
+            using RemoteInvokeHandle remoteHandle = RemoteExecutor.Invoke(static () =>
+            {
+                Assert.Throws<PlatformNotSupportedException>(() => SignatureHelper.GetFieldSigHelper(null));
+                Assert.Throws<PlatformNotSupportedException>(() => SignatureHelper.GetLocalVarSigHelper());
+                Assert.Throws<PlatformNotSupportedException>(() => SignatureHelper.GetMethodSigHelper(CallingConventions.Any, typeof(int)));
+
+                // Mono always throws NotImplementedException - https://github.com/dotnet/runtime/issues/37794
+                if (!PlatformDetection.IsMonoRuntime)
+                {
+                    Assert.Throws<PlatformNotSupportedException>(() => SignatureHelper.GetPropertySigHelper(null, typeof(string), new Type[] { typeof(string), typeof(int) }));
+                }
+            }, options);
+        }
+    }
+}
index 9c67225..fbd2253 100644 (file)
@@ -2,6 +2,7 @@
   <PropertyGroup>
     <TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
     <TestRuntime>true</TestRuntime>
+    <IncludeRemoteExecutor>true</IncludeRemoteExecutor>
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="ILGenerator\DeclareLocalTests.cs" />
@@ -32,6 +33,7 @@
     <Compile Include="SignatureHelper\SignatureHelperGetMethodSigHelper.cs" />
     <Compile Include="SignatureHelper\SignatureHelperGetPropertySigHelper.cs" />
     <Compile Include="SignatureHelper\SignatureHelperGetSignature.cs" />
+    <Compile Include="SignatureHelper\SignatureHelperDynamicCodeNotSupported.cs" />
     <Compile Include="SignatureHelper\SignatureHelperToString.cs" />
     <Compile Include="CustomAttributeBuilderTests.cs" />
     <Compile Include="Utilities.cs" />
index 935d0ab..6844ffa 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System;
+using Microsoft.DotNet.RemoteExecutor;
 using Xunit;
 
 namespace System.Reflection.Emit.Tests
@@ -173,5 +174,30 @@ namespace System.Reflection.Emit.Tests
             AssertExtensions.Throws<ArgumentException>(null, () => new DynamicMethod("Method", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(void), new Type[0], owner, true));
             AssertExtensions.Throws<ArgumentException>(null, () => new DynamicMethod("Method", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(void), new Type[0], owner, false));
         }
+
+        [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
+        public static void ThrowsWhenDynamicCodeNotSupported()
+        {
+            RemoteInvokeOptions options = new RemoteInvokeOptions();
+            options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", false.ToString());
+
+            using RemoteInvokeHandle remoteHandle = RemoteExecutor.Invoke(static () =>
+            {
+                Module module = typeof(TestClass).GetTypeInfo().Module;
+                string name = "Method";
+                Type returnType = typeof(void);
+                Type[] parameterTypes = null;
+                Type owner = typeof(TestClass);
+
+                Assert.Throws<PlatformNotSupportedException>(() => new DynamicMethod(name, returnType, parameterTypes));
+                Assert.Throws<PlatformNotSupportedException>(() => new DynamicMethod(name, returnType, parameterTypes, true));
+                Assert.Throws<PlatformNotSupportedException>(() => new DynamicMethod(name, returnType, parameterTypes, module));
+                Assert.Throws<PlatformNotSupportedException>(() => new DynamicMethod(name, returnType, parameterTypes, owner));
+                Assert.Throws<PlatformNotSupportedException>(() => new DynamicMethod(name, returnType, parameterTypes, module, true));
+                Assert.Throws<PlatformNotSupportedException>(() => new DynamicMethod(name, returnType, parameterTypes, owner, true));
+                Assert.Throws<PlatformNotSupportedException>(() => new DynamicMethod(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, module, true));
+                Assert.Throws<PlatformNotSupportedException>(() => new DynamicMethod(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner, true));
+            }, options);
+        }
     }
 }
index 23d8ff7..eb9e457 100644 (file)
@@ -3,6 +3,7 @@
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
     <TestRuntime>true</TestRuntime>
+    <IncludeRemoteExecutor>true</IncludeRemoteExecutor>
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="DynamicILInfoTests.cs" />
index 43dcc00..b06b20a 100644 (file)
@@ -4,6 +4,7 @@
 using System.Collections.Generic;
 using System.Globalization;
 using System.Linq;
+using Microsoft.DotNet.RemoteExecutor;
 using Xunit;
 
 namespace System.Reflection.Emit.Tests
@@ -442,5 +443,20 @@ namespace System.Reflection.Emit.Tests
         Assert.Empty(internalAssemblyBuilder.Location);
     }
 
+        [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
+        public static void ThrowsWhenDynamicCodeNotSupported()
+        {
+            RemoteInvokeOptions options = new RemoteInvokeOptions();
+            options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", false.ToString());
+
+            using RemoteInvokeHandle remoteHandle = RemoteExecutor.Invoke(static () =>
+            {
+                var assemblyName = new AssemblyName("TestName");
+                AssemblyBuilderAccess access = AssemblyBuilderAccess.Run;
+
+                Assert.Throws<PlatformNotSupportedException>(() => AssemblyBuilder.DefineDynamicAssembly(assemblyName, access));
+                Assert.Throws<PlatformNotSupportedException>(() => AssemblyBuilder.DefineDynamicAssembly(assemblyName, access, assemblyAttributes: null));
+            }, options);
+        }
     }
 }
index 8d00c24..e906d7d 100644 (file)
@@ -2,6 +2,7 @@
   <PropertyGroup>
     <TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
     <TestRuntime>true</TestRuntime>
+    <IncludeRemoteExecutor>true</IncludeRemoteExecutor>
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="AssemblyBuilderTests.cs" />
index e8f19b6..c9a5924 100644 (file)
@@ -5,6 +5,7 @@ using System;
 using System.Collections.Generic;
 using System.Reflection;
 using System.Runtime.CompilerServices;
+using Microsoft.DotNet.RemoteExecutor;
 using Xunit;
 
 namespace System.Runtime.CompilerServices.Tests
@@ -70,5 +71,26 @@ namespace System.Runtime.CompilerServices.Tests
         {
             Assert.True(RuntimeFeature.IsSupported(probedValue));
         }
+
+        [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
+        [InlineData(true)]
+        [InlineData(false)]
+        public static void DynamicCode_ContextSwitch(bool isDynamicCodeSupported)
+        {
+            RemoteInvokeOptions options = new RemoteInvokeOptions();
+            options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", isDynamicCodeSupported.ToString());
+
+            // IsDynamicCodeCompiled on Mono interpreter always returns false
+            bool isDynamicCodeCompiled = PlatformDetection.IsMonoInterpreter ? false : isDynamicCodeSupported;
+
+            using RemoteInvokeHandle remoteHandle = RemoteExecutor.Invoke(static (isDynamicCodeSupportedString, isDynamicCodeCompiledString) =>
+            {
+                bool isDynamicCodeSupported = bool.Parse(isDynamicCodeSupportedString);
+                Assert.Equal(isDynamicCodeSupported, RuntimeFeature.IsDynamicCodeSupported);
+
+                bool isDynamicCodeCompiled = bool.Parse(isDynamicCodeCompiledString);
+                Assert.Equal(isDynamicCodeCompiled, RuntimeFeature.IsDynamicCodeCompiled);
+            }, isDynamicCodeSupported.ToString(), isDynamicCodeCompiled.ToString(), options);
+        }
     }
 }
index 411da5e..50d6090 100644 (file)
       <Compile Include="$(BclSourcesRoot)\System\Runtime\JitInfo.Mono.cs" />
       <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\JitHelpers.cs" />
       <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\RuntimeHelpers.Mono.cs" />
-      <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\RuntimeFeature.Mono.cs" />
       <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\GCHandle.Mono.cs" />
       <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\Marshal.Mono.cs" />
       <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\MemoryMarshal.Mono.cs" />
index c699303..4b21b7c 100644 (file)
@@ -206,6 +206,8 @@ namespace System.Reflection.Emit
         [DynamicDependency(nameof(access))] // Automatically keeps all previous fields too due to StructLayout
         private AssemblyBuilder(AssemblyName n, AssemblyBuilderAccess access)
         {
+            EnsureDynamicCodeSupported();
+
             aname = (AssemblyName)n.Clone();
 
             if (!Enum.IsDefined(typeof(AssemblyBuilderAccess), access))
index 86fa5e3..8133a61 100644 (file)
@@ -177,6 +177,8 @@ namespace System.Reflection.Emit
             ArgumentNullException.ThrowIfNull(namedFields);
             ArgumentNullException.ThrowIfNull(fieldValues);
 
+            AssemblyBuilder.EnsureDynamicCodeSupported();
+
             if (con.GetParametersCount() != constructorArgs.Length)
                 throw new ArgumentException(SR.Argument_BadParameterCountsForConstructor);
             if (namedProperties.Length != propertyValues.Length)
index 8807555..742f7c8 100644 (file)
@@ -65,6 +65,8 @@ namespace System.Reflection.Emit
         [DynamicDependency(nameof(modopts))]  // Automatically keeps all previous fields too due to StructLayout
         internal SignatureHelper(ModuleBuilder? module, SignatureHelperType type)
         {
+            AssemblyBuilder.EnsureDynamicCodeSupported();
+
             this.type = type;
             this.module = module;
         }
diff --git a/src/mono/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.Mono.cs
deleted file mode 100644 (file)
index e54e4dd..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-using System.Reflection;
-
-namespace System.Runtime.CompilerServices
-{
-    public partial class RuntimeFeature
-    {
-        public static bool IsDynamicCodeSupported
-        {
-            [Intrinsic]  // the JIT/AOT compiler will change this flag to false for FullAOT scenarios, otherwise true
-            get => IsDynamicCodeSupported;
-        }
-
-        public static bool IsDynamicCodeCompiled
-        {
-            [Intrinsic]  // the JIT/AOT compiler will change this flag to false for FullAOT scenarios, otherwise true
-            get => IsDynamicCodeCompiled;
-        }
-    }
-}
index 76fac63..6b009b0 100644 (file)
@@ -2608,9 +2608,9 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas
        else if (in_corlib &&
                           !strcmp ("System.Runtime.CompilerServices", klass_name_space) &&
                           !strcmp ("RuntimeFeature", klass_name)) {
-               if (!strcmp (tm, "get_IsDynamicCodeSupported"))
-                       *op = MINT_LDC_I4_1;
-               else if (!strcmp (tm, "get_IsDynamicCodeCompiled"))
+               // NOTE: on the interpreter, use the C# code in System.Private.CoreLib for IsDynamicCodeSupported
+               // and always return false for IsDynamicCodeCompiled
+               if (!strcmp (tm, "get_IsDynamicCodeCompiled"))
                        *op = MINT_LDC_I4_0;
        } else if (in_corlib &&
                        (!strncmp ("System.Runtime.Intrinsics.Arm", klass_name_space, 29) ||
index df07e02..8609823 100644 (file)
@@ -2064,16 +2064,20 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
                }
        }
 
-       // Return false for RuntimeFeature.IsDynamicCodeSupported and RuntimeFeature.IsDynamicCodeCompiled on FullAOT, otherwise true
+       // On FullAOT, return false for RuntimeFeature:
+       // - IsDynamicCodeCompiled 
+       // - IsDynamicCodeSupported and no interpreter
+       // otherwise use the C# code in System.Private.CoreLib
        if (in_corlib &&
+               cfg->full_aot &&
                !strcmp ("System.Runtime.CompilerServices", cmethod_klass_name_space) &&
                !strcmp ("RuntimeFeature", cmethod_klass_name)) {
                if (!strcmp (cmethod->name, "get_IsDynamicCodeCompiled")) {
-                       EMIT_NEW_ICONST (cfg, ins, cfg->full_aot ? 0 : 1);
+                       EMIT_NEW_ICONST (cfg, ins, 0);
                        ins->type = STACK_I4;
                        return ins;
-               } else if (!strcmp (cmethod->name, "get_IsDynamicCodeSupported")) {
-                       EMIT_NEW_ICONST (cfg, ins, cfg->full_aot ? (cfg->interp ? 1 : 0) : 1);
+               } else if (!strcmp (cmethod->name, "get_IsDynamicCodeSupported") && !cfg->interp) {
+                       EMIT_NEW_ICONST (cfg, ins, 0);
                        ins->type = STACK_I4;
                        return ins;
                }
index 96265b5..4fee8f9 100644 (file)
         <ExcludeList Include="$(XunitTestBinBase)/reflection/Modifiers/modifiers/*">
             <Issue>https://github.com/dotnet/runtimelab/issues/201</Issue>
         </ExcludeList>
-        <ExcludeList Include="$(XunitTestBinBase)/reflection/RefEmit/EmittingIgnoresAccessChecksToAttributeIsRespected\EmittingIgnoresAccessChecksToAttributeIsRespected/*">
-            <Issue>https://github.com/dotnet/runtimelab/issues/155: Ref emit</Issue>
-        </ExcludeList>
         <ExcludeList Include="$(XunitTestBinBase)/reflection/SetValue/TrySetReadonlyStaticField/*">
             <Issue>https://github.com/dotnet/runtimelab/issues/200</Issue>
         </ExcludeList>
         <ExcludeList Include = "$(XunitTestBinBase)/Interop/PInvoke/Primitives/Int/PInvokeIntTest/**">
             <Issue>Needs coreclr build</Issue>
         </ExcludeList>
+
+        <ExcludeList Include = "$(XunitTestBinBase)/reflection/RefEmit/EmittingIgnoresAccessChecksToAttributeIsRespected/**">
+            <Issue>Reflection.Emit is not supported on fullaot</Issue>
+        </ExcludeList>
         
     </ItemGroup>