Abstract out System.Reflection.Emit.ILGenerator (#86594)
authorBuyaa Namnan <bunamnan@microsoft.com>
Tue, 23 May 2023 02:36:40 +0000 (19:36 -0700)
committerGitHub <noreply@github.com>
Tue, 23 May 2023 02:36:40 +0000 (19:36 -0700)
* Abstract out ILGenerator

* Finish up abstracting

* Remove protected abstract methods, use more public abstract instead

* Use RuntimeILGenerator for Linq test

17 files changed:
src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj
src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs
src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeILGenerator.cs [moved from src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs with 86% similarity]
src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.cs
src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.cs
src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj
src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs [deleted file]
src/libraries/System.Linq.Expressions/tests/ILReader/DynamicMethodILProvider.cs
src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs [new file with mode: 0644]
src/libraries/System.Reflection.Emit.ILGeneration/ref/System.Reflection.Emit.ILGeneration.cs
src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj
src/mono/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILInfo.cs
src/mono/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.Mono.cs
src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeConstructorBuilder.Mono.cs
src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeILGenerator.Mono.cs [moved from src/mono/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.Mono.cs with 85% similarity]
src/mono/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeMethodBuilder.Mono.cs

index 3b82e34..2632a68 100644 (file)
     <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\CustomAttributeBuilder.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\DynamicILGenerator.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\DynamicMethod.CoreCLR.cs" />
-    <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\ILGenerator.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\LocalBuilder.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\RuntimeAssemblyBuilder.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\RuntimeConstructorBuilder.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\RuntimeEventBuilder.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\RuntimeFieldBuilder.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\RuntimeGenericTypeParameterBuilder.cs" />
+    <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\RuntimeILGenerator.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\RuntimeMethodBuilder.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\RuntimeModuleBuilder.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\RuntimeParameterBuilder.cs" />
index 88dbeff..ee72bab 100644 (file)
@@ -8,7 +8,7 @@ using System.Diagnostics;
 
 namespace System.Reflection.Emit
 {
-    internal sealed class DynamicILGenerator : ILGenerator
+    internal sealed class DynamicILGenerator : RuntimeILGenerator
     {
         internal DynamicScope m_scope;
         private readonly int m_methodSigToken;
@@ -105,7 +105,6 @@ namespace System.Reflection.Emit
             }
 
             UpdateStackSize(opcode, stackchange);
-
             PutInteger4(token);
         }
 
@@ -131,7 +130,6 @@ namespace System.Reflection.Emit
 
             // need to sort out the stack size story
             UpdateStackSize(opcode, 1);
-
             PutInteger4(token);
         }
 
@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
 
 namespace System.Reflection.Emit
 {
-    public class ILGenerator
+    internal class RuntimeILGenerator : ILGenerator
     {
         #region Const Members
         private const int DefaultSize = 16;
@@ -78,11 +78,11 @@ namespace System.Reflection.Emit
         #region Constructor
         // package private constructor. This code path is used when client create
         // ILGenerator through MethodBuilder.
-        internal ILGenerator(MethodInfo methodBuilder) : this(methodBuilder, 64)
+        internal RuntimeILGenerator(MethodInfo methodBuilder) : this(methodBuilder, 64)
         {
         }
 
-        internal ILGenerator(MethodInfo methodBuilder, int size)
+        internal RuntimeILGenerator(MethodInfo methodBuilder, int size)
         {
             Debug.Assert(methodBuilder != null);
             Debug.Assert(methodBuilder is MethodBuilder || methodBuilder is DynamicMethod);
@@ -177,18 +177,7 @@ namespace System.Reflection.Emit
             Type[]? parameterTypes,
             Type[]? optionalParameterTypes)
         {
-            return GetMemberRefSignature(call, returnType, parameterTypes, null, null, optionalParameterTypes);
-        }
-        internal virtual SignatureHelper GetMemberRefSignature(CallingConventions call, Type? returnType,
-            Type[]? parameterTypes, Type[][]? requiredCustomModifiers, Type[][]? optionalCustomModifiers, Type[]? optionalParameterTypes)
-        {
-            return GetMemberRefSignature(call, returnType, parameterTypes, requiredCustomModifiers, optionalCustomModifiers, optionalParameterTypes, 0);
-        }
-
-        private SignatureHelper GetMemberRefSignature(CallingConventions call, Type? returnType,
-            Type[]? parameterTypes, Type[][]? requiredCustomModifiers, Type[][]? optionalCustomModifiers, Type[]? optionalParameterTypes, int cGenericParameters)
-        {
-            return ((RuntimeModuleBuilder)m_methodBuilder.Module).GetMemberRefSignature(call, returnType, parameterTypes, requiredCustomModifiers, optionalCustomModifiers, optionalParameterTypes, cGenericParameters);
+            return ((RuntimeModuleBuilder)m_methodBuilder.Module).GetMemberRefSignature(call, returnType, parameterTypes, null, null, optionalParameterTypes, 0);
         }
 
         internal byte[]? BakeByteArray()
@@ -383,29 +372,20 @@ namespace System.Reflection.Emit
         #region Public Members
 
         #region Emit
-        public virtual void Emit(OpCode opcode)
+        public override void Emit(OpCode opcode)
         {
             EnsureCapacity(3);
             InternalEmit(opcode);
         }
 
-        public virtual void Emit(OpCode opcode, byte arg)
+        public override void Emit(OpCode opcode, byte arg)
         {
             EnsureCapacity(4);
             InternalEmit(opcode);
             m_ILStream[m_length++] = arg;
         }
 
-        [CLSCompliant(false)]
-        public void Emit(OpCode opcode, sbyte arg)
-        {
-            // Puts opcode onto the stream of instructions followed by arg
-            EnsureCapacity(4);
-            InternalEmit(opcode);
-            m_ILStream[m_length++] = (byte)arg;
-        }
-
-        public virtual void Emit(OpCode opcode, short arg)
+        public override void Emit(OpCode opcode, short arg)
         {
             // Puts opcode onto the stream of instructions followed by arg
             EnsureCapacity(5);
@@ -414,7 +394,7 @@ namespace System.Reflection.Emit
             m_length += 2;
         }
 
-        public virtual void Emit(OpCode opcode, int arg)
+        public override void Emit(OpCode opcode, int arg)
         {
             // Special-case several opcodes that have shorter variants for common values.
             if (opcode.Equals(OpCodes.Ldc_I4))
@@ -505,7 +485,7 @@ namespace System.Reflection.Emit
             PutInteger4(arg);
         }
 
-        public virtual void Emit(OpCode opcode, MethodInfo meth)
+        public override void Emit(OpCode opcode, MethodInfo meth)
         {
             ArgumentNullException.ThrowIfNull(meth);
 
@@ -531,7 +511,7 @@ namespace System.Reflection.Emit
             }
         }
 
-        public virtual void EmitCalli(OpCode opcode, CallingConventions callingConvention,
+        public override void EmitCalli(OpCode opcode, CallingConventions callingConvention,
             Type? returnType, Type[]? parameterTypes, Type[]? optionalParameterTypes)
         {
             int stackchange = 0;
@@ -573,7 +553,7 @@ namespace System.Reflection.Emit
             PutInteger4(modBuilder.GetSignatureMetadataToken(sig));
         }
 
-        public virtual void EmitCalli(OpCode opcode, CallingConvention unmanagedCallConv, Type? returnType, Type[]? parameterTypes)
+        public override void EmitCalli(OpCode opcode, CallingConvention unmanagedCallConv, Type? returnType, Type[]? parameterTypes)
         {
             int stackchange = 0;
             int cParams = 0;
@@ -616,7 +596,7 @@ namespace System.Reflection.Emit
             PutInteger4(modBuilder.GetSignatureMetadataToken(sig));
         }
 
-        public virtual void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[]? optionalParameterTypes)
+        public override void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[]? optionalParameterTypes)
         {
             ArgumentNullException.ThrowIfNull(methodInfo);
 
@@ -650,7 +630,7 @@ namespace System.Reflection.Emit
             PutInteger4(tk);
         }
 
-        public virtual void Emit(OpCode opcode, SignatureHelper signature)
+        public override void Emit(OpCode opcode, SignatureHelper signature)
         {
             ArgumentNullException.ThrowIfNull(signature);
 
@@ -683,7 +663,7 @@ namespace System.Reflection.Emit
             PutInteger4(tempVal);
         }
 
-        public virtual void Emit(OpCode opcode, ConstructorInfo con)
+        public override void Emit(OpCode opcode, ConstructorInfo con)
         {
             ArgumentNullException.ThrowIfNull(con);
 
@@ -723,7 +703,7 @@ namespace System.Reflection.Emit
             PutInteger4(tk);
         }
 
-        public virtual void Emit(OpCode opcode, Type cls)
+        public override void Emit(OpCode opcode, Type cls)
         {
             // Puts opcode onto the stream and then the metadata token represented
             // by cls.  The location of cls is recorded so that the token can be
@@ -739,7 +719,7 @@ namespace System.Reflection.Emit
             PutInteger4(tempVal);
         }
 
-        public virtual void Emit(OpCode opcode, long arg)
+        public override void Emit(OpCode opcode, long arg)
         {
             EnsureCapacity(11);
             InternalEmit(opcode);
@@ -747,7 +727,7 @@ namespace System.Reflection.Emit
             m_length += 8;
         }
 
-        public virtual void Emit(OpCode opcode, float arg)
+        public override void Emit(OpCode opcode, float arg)
         {
             EnsureCapacity(7);
             InternalEmit(opcode);
@@ -755,7 +735,7 @@ namespace System.Reflection.Emit
             m_length += 4;
         }
 
-        public virtual void Emit(OpCode opcode, double arg)
+        public override void Emit(OpCode opcode, double arg)
         {
             EnsureCapacity(11);
             InternalEmit(opcode);
@@ -763,7 +743,7 @@ namespace System.Reflection.Emit
             m_length += 8;
         }
 
-        public virtual void Emit(OpCode opcode, Label label)
+        public override void Emit(OpCode opcode, Label label)
         {
             // Puts opcode onto the stream and leaves space to include label
             // when fixups are done.  Labels are created using ILGenerator.DefineLabel and
@@ -789,7 +769,7 @@ namespace System.Reflection.Emit
             }
         }
 
-        public virtual void Emit(OpCode opcode, Label[] labels)
+        public override void Emit(OpCode opcode, Label[] labels)
         {
             ArgumentNullException.ThrowIfNull(labels);
 
@@ -811,7 +791,7 @@ namespace System.Reflection.Emit
             }
         }
 
-        public virtual void Emit(OpCode opcode, FieldInfo field)
+        public override void Emit(OpCode opcode, FieldInfo field)
         {
             ModuleBuilder modBuilder = (ModuleBuilder)m_methodBuilder.Module;
             int tempVal = modBuilder.GetFieldMetadataToken(field);
@@ -821,7 +801,7 @@ namespace System.Reflection.Emit
             PutInteger4(tempVal);
         }
 
-        public virtual void Emit(OpCode opcode, string str)
+        public override void Emit(OpCode opcode, string str)
         {
             // Puts the opcode onto the IL stream followed by the metadata token
             // represented by str.  The location of str is recorded for future
@@ -834,7 +814,7 @@ namespace System.Reflection.Emit
             PutInteger4(tempVal);
         }
 
-        public virtual void Emit(OpCode opcode, LocalBuilder local)
+        public override void Emit(OpCode opcode, LocalBuilder local)
         {
             ArgumentNullException.ThrowIfNull(local);
 
@@ -919,7 +899,7 @@ namespace System.Reflection.Emit
         #endregion
 
         #region Exceptions
-        public virtual Label BeginExceptionBlock()
+        public override Label BeginExceptionBlock()
         {
             // Begin an Exception block.  Creating an Exception block records some information,
             // but does not actually emit any IL onto the stream.  Exceptions should be created and
@@ -962,7 +942,7 @@ namespace System.Reflection.Emit
             return endLabel;
         }
 
-        public virtual void EndExceptionBlock()
+        public override void EndExceptionBlock()
         {
             if (m_currExcStackCount == 0)
             {
@@ -1003,7 +983,7 @@ namespace System.Reflection.Emit
             current.Done(m_length);
         }
 
-        public virtual void BeginExceptFilterBlock()
+        public override void BeginExceptFilterBlock()
         {
             // Begins an exception filter block.  Emits a branch instruction to the end of the current exception block.
 
@@ -1020,7 +1000,7 @@ namespace System.Reflection.Emit
             m_curDepth = 1;
         }
 
-        public virtual void BeginCatchBlock(Type? exceptionType)
+        public override void BeginCatchBlock(Type? exceptionType)
         {
             // Begins a catch block.  Emits a branch instruction to the end of the current exception block.
 
@@ -1053,7 +1033,7 @@ namespace System.Reflection.Emit
             m_curDepth = 1;
         }
 
-        public virtual void BeginFaultBlock()
+        public override void BeginFaultBlock()
         {
             if (m_currExcStackCount == 0)
             {
@@ -1070,7 +1050,7 @@ namespace System.Reflection.Emit
             m_curDepth = 0;
         }
 
-        public virtual void BeginFinallyBlock()
+        public override void BeginFinallyBlock()
         {
             if (m_currExcStackCount == 0)
             {
@@ -1105,7 +1085,7 @@ namespace System.Reflection.Emit
         #endregion
 
         #region Labels
-        public virtual Label DefineLabel()
+        public override Label DefineLabel()
         {
             // We don't know the stack depth at the label yet, so set it to -1.
             return DefineLabel(-1);
@@ -1130,7 +1110,7 @@ namespace System.Reflection.Emit
             return new Label(m_labelCount++);
         }
 
-        public virtual void MarkLabel(Label loc)
+        public override void MarkLabel(Label loc)
         {
             // Defines a label by setting the position where that label is found within the stream.
             // Does not allow a label to be defined more than once.
@@ -1180,119 +1160,8 @@ namespace System.Reflection.Emit
 
         #endregion
 
-        #region IL Macros
-        public virtual void ThrowException([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type excType)
-        {
-            // Emits the il to throw an exception
-
-            ArgumentNullException.ThrowIfNull(excType);
-
-            if (!excType.IsSubclassOf(typeof(Exception)) && excType != typeof(Exception))
-            {
-                throw new ArgumentException(SR.Argument_NotExceptionType, nameof(excType));
-            }
-            ConstructorInfo? con = excType.GetConstructor(Type.EmptyTypes);
-            if (con == null)
-            {
-                throw new ArgumentException(SR.Arg_NoDefCTorWithoutTypeName, nameof(excType));
-            }
-            Emit(OpCodes.Newobj, con);
-            Emit(OpCodes.Throw);
-        }
-
-        private const string ConsoleTypeFullName = "System.Console, System.Console";
-
-        public virtual void EmitWriteLine(string value)
-        {
-            // Emits the IL to call Console.WriteLine with a string.
-
-            Emit(OpCodes.Ldstr, value);
-            Type[] parameterTypes = new Type[1];
-            parameterTypes[0] = typeof(string);
-            Type consoleType = Type.GetType(ConsoleTypeFullName, throwOnError: true)!;
-            MethodInfo mi = consoleType.GetMethod("WriteLine", parameterTypes)!;
-            Emit(OpCodes.Call, mi);
-        }
-
-        public virtual void EmitWriteLine(LocalBuilder localBuilder)
-        {
-            // Emits the IL necessary to call WriteLine with lcl.  It is
-            // an error to call EmitWriteLine with a lcl which is not of
-            // one of the types for which Console.WriteLine implements overloads. (e.g.
-            // we do *not* call ToString on the locals.
-
-            if (m_methodBuilder == null)
-            {
-                throw new ArgumentException(SR.InvalidOperation_BadILGeneratorUsage);
-            }
-
-            Type consoleType = Type.GetType(ConsoleTypeFullName, throwOnError: true)!;
-            MethodInfo prop = consoleType.GetMethod("get_Out")!;
-            Emit(OpCodes.Call, prop);
-            Emit(OpCodes.Ldloc, localBuilder);
-            Type[] parameterTypes = new Type[1];
-            Type cls = localBuilder.LocalType;
-            if (cls is TypeBuilder || cls is EnumBuilder)
-            {
-                throw new ArgumentException(SR.NotSupported_OutputStreamUsingTypeBuilder);
-            }
-            parameterTypes[0] = cls;
-            MethodInfo? mi = typeof(System.IO.TextWriter).GetMethod("WriteLine", parameterTypes);
-            if (mi == null)
-            {
-                throw new ArgumentException(SR.Argument_EmitWriteLineType, nameof(localBuilder));
-            }
-
-            Emit(OpCodes.Callvirt, mi);
-        }
-
-        public virtual void EmitWriteLine(FieldInfo fld)
-        {
-            ArgumentNullException.ThrowIfNull(fld);
-
-            // Emits the IL necessary to call WriteLine with fld.  It is
-            // an error to call EmitWriteLine with a fld which is not of
-            // one of the types for which Console.WriteLine implements overloads. (e.g.
-            // we do *not* call ToString on the fields.
-
-            Type consoleType = Type.GetType(ConsoleTypeFullName, throwOnError: true)!;
-            MethodInfo prop = consoleType.GetMethod("get_Out")!;
-            Emit(OpCodes.Call, prop);
-
-            if ((fld.Attributes & FieldAttributes.Static) != 0)
-            {
-                Emit(OpCodes.Ldsfld, fld);
-            }
-            else
-            {
-                Emit(OpCodes.Ldarg_0); // Load the this ref.
-                Emit(OpCodes.Ldfld, fld);
-            }
-            Type[] parameterTypes = new Type[1];
-            Type cls = fld.FieldType;
-            if (cls is TypeBuilder || cls is EnumBuilder)
-            {
-                throw new NotSupportedException(SR.NotSupported_OutputStreamUsingTypeBuilder);
-            }
-            parameterTypes[0] = cls;
-            MethodInfo? mi = typeof(System.IO.TextWriter).GetMethod("WriteLine", parameterTypes);
-            if (mi == null)
-            {
-                throw new ArgumentException(SR.Argument_EmitWriteLineType, nameof(fld));
-            }
-
-            Emit(OpCodes.Callvirt, mi);
-        }
-
-        #endregion
-
         #region Debug API
-        public virtual LocalBuilder DeclareLocal(Type localType)
-        {
-            return DeclareLocal(localType, false);
-        }
-
-        public virtual LocalBuilder DeclareLocal(Type localType, bool pinned)
+        public override LocalBuilder DeclareLocal(Type localType, bool pinned)
         {
             // Declare a local of type "local". The current active lexical scope
             // will be the scope that local will live.
@@ -1319,7 +1188,7 @@ namespace System.Reflection.Emit
             return new LocalBuilder(m_localCount++, localType, methodBuilder, pinned);
         }
 
-        public virtual void UsingNamespace(string usingNamespace)
+        public override void UsingNamespace(string usingNamespace)
         {
             // Specifying the namespace to be used in evaluating locals and watches
             // for the current active lexical scope.
@@ -1329,7 +1198,7 @@ namespace System.Reflection.Emit
             if (m_methodBuilder is not RuntimeMethodBuilder methodBuilder)
                 throw new NotSupportedException();
 
-            int index = methodBuilder.GetILGenerator().m_ScopeTree.GetCurrentActiveScopeIndex();
+            int index = ((RuntimeILGenerator)methodBuilder.GetILGenerator()).m_ScopeTree.GetCurrentActiveScopeIndex();
             if (index == -1)
             {
                 methodBuilder.m_localSymInfo!.AddUsingNamespace(usingNamespace);
@@ -1340,17 +1209,17 @@ namespace System.Reflection.Emit
             }
         }
 
-        public virtual void BeginScope()
+        public override void BeginScope()
         {
             m_ScopeTree.AddScopeInfo(ScopeAction.Open, m_length);
         }
 
-        public virtual void EndScope()
+        public override void EndScope()
         {
             m_ScopeTree.AddScopeInfo(ScopeAction.Close, m_length);
         }
 
-        public virtual int ILOffset => m_length;
+        public override int ILOffset => m_length;
 
         #endregion
 
@@ -1424,11 +1293,11 @@ namespace System.Reflection.Emit
             int currentCatch = m_currentCatch;
             if (currentCatch >= m_catchAddr.Length)
             {
-                m_filterAddr = ILGenerator.EnlargeArray(m_filterAddr);
-                m_catchAddr = ILGenerator.EnlargeArray(m_catchAddr);
-                m_catchEndAddr = ILGenerator.EnlargeArray(m_catchEndAddr);
-                m_catchClass = ILGenerator.EnlargeArray(m_catchClass);
-                m_type = ILGenerator.EnlargeArray(m_type);
+                m_filterAddr = RuntimeILGenerator.EnlargeArray(m_filterAddr);
+                m_catchAddr = RuntimeILGenerator.EnlargeArray(m_catchAddr);
+                m_catchEndAddr = RuntimeILGenerator.EnlargeArray(m_catchEndAddr);
+                m_catchClass = RuntimeILGenerator.EnlargeArray(m_catchClass);
+                m_type = RuntimeILGenerator.EnlargeArray(m_type);
             }
             if (type == Filter)
             {
index ecf34b5..f0cf9e6 100644 (file)
@@ -26,7 +26,7 @@ namespace System.Reflection.Emit
         private int[]? m_mdMethodFixups;              // The location of all of the token fixups. Null means no fixups.
         private byte[]? m_localSignature;             // Local signature if set explicitly via DefineBody. Null otherwise.
         internal LocalSymInfo? m_localSymInfo;        // keep track debugging local information
-        internal ILGenerator? m_ilGenerator;          // Null if not used.
+        internal RuntimeILGenerator? m_ilGenerator;   // Null if not used.
         private byte[]? m_ubBody;                     // The IL for the method
         private ExceptionHandler[]? m_exceptions; // Exception handlers or null if there are none.
         private const int DefaultMaxStack = 16;
@@ -130,7 +130,7 @@ namespace System.Reflection.Emit
 
         #region Internal Members
 
-        internal void CreateMethodBodyHelper(ILGenerator il)
+        internal void CreateMethodBodyHelper(RuntimeILGenerator il)
         {
             ArgumentNullException.ThrowIfNull(il);
 
@@ -668,7 +668,7 @@ namespace System.Reflection.Emit
             ThrowIfGeneric();
             ThrowIfShouldNotHaveBody();
 
-            return m_ilGenerator ??= new ILGenerator(this, size);
+            return m_ilGenerator ??= new RuntimeILGenerator(this, size);
         }
 
         private void ThrowIfShouldNotHaveBody()
index 47b7191..79aaaeb 100644 (file)
@@ -1709,7 +1709,7 @@ namespace System.Reflection.Emit
                     if (meth.m_ilGenerator != null)
                     {
                         // we need to bake the method here.
-                        meth.CreateMethodBodyHelper(meth.GetILGenerator());
+                        meth.CreateMethodBodyHelper(((RuntimeILGenerator)meth.GetILGenerator()));
                     }
 
                     body = meth.GetBody();
index 4c728e8..945077f 100644 (file)
     <Compile Include="System\Reflection\Emit\CustomAttributeBuilder.cs" />
     <Compile Include="System\Reflection\Emit\DynamicILInfo.cs" />
     <Compile Include="System\Reflection\Emit\DynamicMethod.cs" />
-    <Compile Include="System\Reflection\Emit\ILGenerator.cs" />
     <Compile Include="System\Reflection\Emit\LocalBuilder.cs" />
     <Compile Include="System\Reflection\Emit\ReflectionEmitThrower.cs" />
     <Compile Include="System\Reflection\Emit\SignatureHelper.cs" />
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs
deleted file mode 100644 (file)
index 49190e8..0000000
+++ /dev/null
@@ -1,177 +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.Diagnostics.CodeAnalysis;
-using System.Runtime.InteropServices;
-
-namespace System.Reflection.Emit
-{
-    public partial class ILGenerator
-    {
-        internal ILGenerator()
-        {
-            // Prevent generating a default constructor
-        }
-
-        public virtual int ILOffset
-        {
-            get
-            {
-                return default;
-            }
-        }
-
-        public virtual void BeginCatchBlock(Type? exceptionType)
-        {
-        }
-
-        public virtual void BeginExceptFilterBlock()
-        {
-        }
-
-        public virtual Label BeginExceptionBlock()
-        {
-            return default;
-        }
-
-        public virtual void BeginFaultBlock()
-        {
-        }
-
-        public virtual void BeginFinallyBlock()
-        {
-        }
-
-        public virtual void BeginScope()
-        {
-        }
-
-        public virtual LocalBuilder DeclareLocal(Type localType)
-        {
-            return default;
-        }
-
-        public virtual LocalBuilder DeclareLocal(Type localType, bool pinned)
-        {
-            return default;
-        }
-
-        public virtual Label DefineLabel()
-        {
-            return default;
-        }
-
-        public virtual void Emit(OpCode opcode)
-        {
-        }
-
-        public virtual void Emit(OpCode opcode, byte arg)
-        {
-        }
-
-        public virtual void Emit(OpCode opcode, double arg)
-        {
-        }
-
-        public virtual void Emit(OpCode opcode, short arg)
-        {
-        }
-
-        public virtual void Emit(OpCode opcode, int arg)
-        {
-        }
-
-        public virtual void Emit(OpCode opcode, long arg)
-        {
-        }
-
-        public virtual void Emit(OpCode opcode, ConstructorInfo con)
-        {
-        }
-
-        public virtual void Emit(OpCode opcode, Label label)
-        {
-        }
-
-        public virtual void Emit(OpCode opcode, Label[] labels)
-        {
-        }
-
-        public virtual void Emit(OpCode opcode, LocalBuilder local)
-        {
-        }
-
-        public virtual void Emit(OpCode opcode, SignatureHelper signature)
-        {
-        }
-
-        public virtual void Emit(OpCode opcode, FieldInfo field)
-        {
-        }
-
-        public virtual void Emit(OpCode opcode, MethodInfo meth)
-        {
-        }
-
-        [CLSCompliantAttribute(false)]
-        public void Emit(OpCode opcode, sbyte arg)
-        {
-        }
-
-        public virtual void Emit(OpCode opcode, float arg)
-        {
-        }
-
-        public virtual void Emit(OpCode opcode, string str)
-        {
-        }
-
-        public virtual void Emit(OpCode opcode, Type cls)
-        {
-        }
-
-        public virtual void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[] optionalParameterTypes)
-        {
-        }
-
-        public virtual void EmitCalli(OpCode opcode, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes)
-        {
-        }
-
-        public virtual void EmitCalli(OpCode opcode, CallingConvention unmanagedCallConv, Type returnType, Type[] parameterTypes)
-        {
-        }
-
-        public virtual void EmitWriteLine(LocalBuilder localBuilder)
-        {
-        }
-
-        public virtual void EmitWriteLine(FieldInfo fld)
-        {
-        }
-
-        public virtual void EmitWriteLine(string value)
-        {
-        }
-
-        public virtual void EndExceptionBlock()
-        {
-        }
-
-        public virtual void EndScope()
-        {
-        }
-
-        public virtual void MarkLabel(Label loc)
-        {
-        }
-
-        public virtual void ThrowException([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type excType)
-        {
-        }
-
-        public virtual void UsingNamespace(string usingNamespace)
-        {
-        }
-    }
-}
index 04bb2bb..8ecd1a2 100644 (file)
@@ -10,13 +10,14 @@ namespace System.Linq.Expressions.Tests
 {
     public sealed class DynamicMethodILProvider : IILProvider
     {
-        private static readonly FieldInfo s_fiLen = typeof(ILGenerator).GetFieldAssert("m_length");
-        private static readonly FieldInfo s_fiStream = typeof(ILGenerator).GetFieldAssert("m_ILStream");
-        private static readonly FieldInfo s_fiExceptions = typeof(ILGenerator).GetFieldAssert("m_exceptions");
-        private static readonly FieldInfo s_fiExceptionCount = typeof(ILGenerator).GetFieldAssert("m_exceptionCount");
-        private static readonly FieldInfo s_fiLocalSignature = typeof(ILGenerator).GetFieldAssert("m_localSignature");
-        private static readonly MethodInfo s_miBakeByteArray = typeof(ILGenerator).GetMethodAssert("BakeByteArray");
-        private static readonly MethodInfo s_miMaxStackSize = typeof(ILGenerator).GetMethodAssert("GetMaxStackSize");
+        private static readonly Type s_runtimeILGenerator = Type.GetType("System.Reflection.Emit.RuntimeILGenerator");
+        private static readonly FieldInfo s_fiLen = s_runtimeILGenerator.GetFieldAssert("m_length");
+        private static readonly FieldInfo s_fiStream = s_runtimeILGenerator.GetFieldAssert("m_ILStream");
+        private static readonly FieldInfo s_fiExceptions = s_runtimeILGenerator.GetFieldAssert("m_exceptions");
+        private static readonly FieldInfo s_fiExceptionCount = s_runtimeILGenerator.GetFieldAssert("m_exceptionCount");
+        private static readonly FieldInfo s_fiLocalSignature = s_runtimeILGenerator.GetFieldAssert("m_localSignature");
+        private static readonly MethodInfo s_miBakeByteArray = s_runtimeILGenerator.GetMethodAssert("BakeByteArray");
+        private static readonly MethodInfo s_miMaxStackSize = s_runtimeILGenerator.GetMethodAssert("GetMaxStackSize");
 
         private readonly DynamicMethod _method;
         private byte[] _byteArray;
index 10b27e3..63fbe77 100644 (file)
     <Compile Include="$(MSBuildThisFileDirectory)System\IFormatProvider.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\IFormattable.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Index.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\Emit\ILGenerator.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\SearchValues\BitVector256.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\SearchValues\SingleCharSearchValues.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\SearchValues\SingleByteSearchValues.cs" />
diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs
new file mode 100644 (file)
index 0000000..84ae8bb
--- /dev/null
@@ -0,0 +1,200 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.InteropServices;
+
+namespace System.Reflection.Emit
+{
+    public abstract class ILGenerator
+    {
+        protected ILGenerator()
+        {
+        }
+
+        #region Public Members
+
+        #region Emit
+        public abstract void Emit(OpCode opcode);
+
+        public abstract void Emit(OpCode opcode, byte arg);
+
+        public abstract void Emit(OpCode opcode, short arg);
+
+        public abstract void Emit(OpCode opcode, long arg);
+
+        public abstract void Emit(OpCode opcode, float arg);
+
+        public abstract void Emit(OpCode opcode, double arg);
+
+        public abstract void Emit(OpCode opcode, int arg);
+
+        public abstract void Emit(OpCode opcode, MethodInfo meth);
+
+        public abstract void EmitCalli(OpCode opcode, CallingConventions callingConvention,
+            Type? returnType, Type[]? parameterTypes, Type[]? optionalParameterTypes);
+
+        public abstract void EmitCalli(OpCode opcode, CallingConvention unmanagedCallConv, Type? returnType, Type[]? parameterTypes);
+
+        public abstract void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[]? optionalParameterTypes);
+
+        public abstract void Emit(OpCode opcode, SignatureHelper signature);
+
+        public abstract void Emit(OpCode opcode, ConstructorInfo con);
+
+        public abstract void Emit(OpCode opcode, Type cls);
+
+        public abstract void Emit(OpCode opcode, Label label);
+
+        public abstract void Emit(OpCode opcode, Label[] labels);
+
+        public abstract void Emit(OpCode opcode, FieldInfo field);
+
+        public abstract void Emit(OpCode opcode, string str);
+
+        public abstract void Emit(OpCode opcode, LocalBuilder local);
+        #endregion
+
+        #region Exceptions
+        public abstract Label BeginExceptionBlock();
+
+        public abstract void EndExceptionBlock();
+
+        public abstract void BeginExceptFilterBlock();
+
+        public abstract void BeginCatchBlock(Type? exceptionType);
+
+        public abstract void BeginFaultBlock();
+
+        public abstract void BeginFinallyBlock();
+
+        #endregion
+
+        #region Labels
+        public abstract Label DefineLabel();
+
+        public abstract void MarkLabel(Label loc);
+
+        #endregion
+
+        #region IL Macros
+        public virtual void ThrowException([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type excType)
+        {
+            // Emits the il to throw an exception
+            ArgumentNullException.ThrowIfNull(excType);
+
+            if (!excType.IsSubclassOf(typeof(Exception)) && excType != typeof(Exception))
+            {
+                throw new ArgumentException(SR.Argument_NotExceptionType, nameof(excType));
+            }
+            ConstructorInfo? con = excType.GetConstructor(Type.EmptyTypes);
+            if (con == null)
+            {
+                throw new ArgumentException(SR.Arg_NoDefCTorWithoutTypeName, nameof(excType));
+            }
+            Emit(OpCodes.Newobj, con);
+            Emit(OpCodes.Throw);
+        }
+
+        private const string ConsoleTypeFullName = "System.Console, System.Console";
+        private static readonly Type[] s_parameterTypes = new Type[] { typeof(string) };
+
+        public virtual void EmitWriteLine(string value)
+        {
+            // Emits the IL to call Console.WriteLine with a string.
+            Emit(OpCodes.Ldstr, value);
+            Type consoleType = Type.GetType(ConsoleTypeFullName, throwOnError: true)!;
+            MethodInfo mi = consoleType.GetMethod("WriteLine", s_parameterTypes)!;
+            Emit(OpCodes.Call, mi);
+        }
+
+        public virtual void EmitWriteLine(LocalBuilder localBuilder)
+        {
+            // Emits the IL necessary to call WriteLine with lcl.  It is
+            // an error to call EmitWriteLine with a lcl which is not of
+            // one of the types for which Console.WriteLine implements overloads. (e.g.
+            // we do *not* call ToString on the locals.
+
+            Type consoleType = Type.GetType(ConsoleTypeFullName, throwOnError: true)!;
+            MethodInfo prop = consoleType.GetMethod("get_Out")!;
+            Emit(OpCodes.Call, prop);
+            Emit(OpCodes.Ldloc, localBuilder);
+            Type[] parameterTypes = new Type[1];
+            Type cls = localBuilder.LocalType;
+            if (cls is TypeBuilder || cls is EnumBuilder)
+            {
+                throw new ArgumentException(SR.NotSupported_OutputStreamUsingTypeBuilder);
+            }
+            parameterTypes[0] = cls;
+            MethodInfo? mi = typeof(System.IO.TextWriter).GetMethod("WriteLine", parameterTypes);
+            if (mi == null)
+            {
+                throw new ArgumentException(SR.Argument_EmitWriteLineType, nameof(localBuilder));
+            }
+
+            Emit(OpCodes.Callvirt, mi);
+        }
+
+        public virtual void EmitWriteLine(FieldInfo fld)
+        {
+            ArgumentNullException.ThrowIfNull(fld);
+
+            // Emits the IL necessary to call WriteLine with fld.  It is
+            // an error to call EmitWriteLine with a fld which is not of
+            // one of the types for which Console.WriteLine implements overloads. (e.g.
+            // we do *not* call ToString on the fields.
+            Type consoleType = Type.GetType(ConsoleTypeFullName, throwOnError: true)!;
+            MethodInfo prop = consoleType.GetMethod("get_Out")!;
+            Emit(OpCodes.Call, prop);
+
+            if ((fld.Attributes & FieldAttributes.Static) != 0)
+            {
+                Emit(OpCodes.Ldsfld, fld);
+            }
+            else
+            {
+                Emit(OpCodes.Ldarg_0); // Load the this ref.
+                Emit(OpCodes.Ldfld, fld);
+            }
+            Type[] parameterTypes = new Type[1];
+            Type cls = fld.FieldType;
+            if (cls is TypeBuilder || cls is EnumBuilder)
+            {
+                throw new NotSupportedException(SR.NotSupported_OutputStreamUsingTypeBuilder);
+            }
+            parameterTypes[0] = cls;
+            MethodInfo? mi = typeof(System.IO.TextWriter).GetMethod("WriteLine", parameterTypes);
+            if (mi == null)
+            {
+                throw new ArgumentException(SR.Argument_EmitWriteLineType, nameof(fld));
+            }
+
+            Emit(OpCodes.Callvirt, mi);
+        }
+
+        #endregion
+
+        #region Debug API
+        public virtual LocalBuilder DeclareLocal(Type localType)
+        {
+            return DeclareLocal(localType, false);
+        }
+
+        public abstract LocalBuilder DeclareLocal(Type localType, bool pinned);
+
+        public abstract void UsingNamespace(string usingNamespace);
+
+        public abstract void BeginScope();
+
+        public abstract void EndScope();
+
+        public abstract int ILOffset { get; }
+
+        [CLSCompliant(false)]
+        public void Emit(OpCode opcode, sbyte arg) => Emit(opcode, (byte)arg);
+
+        #endregion
+
+        #endregion
+    }
+}
index 1a200d8..93f7313 100644 (file)
@@ -13,48 +13,48 @@ namespace System.Reflection.Emit
         public CustomAttributeBuilder(System.Reflection.ConstructorInfo con, object?[] constructorArgs, System.Reflection.PropertyInfo[] namedProperties, object?[] propertyValues) { }
         public CustomAttributeBuilder(System.Reflection.ConstructorInfo con, object?[] constructorArgs, System.Reflection.PropertyInfo[] namedProperties, object?[] propertyValues, System.Reflection.FieldInfo[] namedFields, object?[] fieldValues) { }
     }
-    public partial class ILGenerator
+    public abstract class ILGenerator
     {
-        internal ILGenerator() { }
-        public virtual int ILOffset { get { throw null; } }
-        public virtual void BeginCatchBlock(System.Type? exceptionType) { }
-        public virtual void BeginExceptFilterBlock() { }
-        public virtual System.Reflection.Emit.Label BeginExceptionBlock() { throw null; }
-        public virtual void BeginFaultBlock() { }
-        public virtual void BeginFinallyBlock() { }
-        public virtual void BeginScope() { }
+        protected ILGenerator() { }
+        public abstract int ILOffset { get; }
+        public abstract void BeginCatchBlock(System.Type? exceptionType);
+        public abstract void BeginExceptFilterBlock();
+        public abstract System.Reflection.Emit.Label BeginExceptionBlock();
+        public abstract void BeginFaultBlock();
+        public abstract void BeginFinallyBlock();
+        public abstract void BeginScope();
         public virtual System.Reflection.Emit.LocalBuilder DeclareLocal(System.Type localType) { throw null; }
-        public virtual System.Reflection.Emit.LocalBuilder DeclareLocal(System.Type localType, bool pinned) { throw null; }
-        public virtual System.Reflection.Emit.Label DefineLabel() { throw null; }
-        public virtual void Emit(System.Reflection.Emit.OpCode opcode) { }
-        public virtual void Emit(System.Reflection.Emit.OpCode opcode, byte arg) { }
-        public virtual void Emit(System.Reflection.Emit.OpCode opcode, double arg) { }
-        public virtual void Emit(System.Reflection.Emit.OpCode opcode, short arg) { }
-        public virtual void Emit(System.Reflection.Emit.OpCode opcode, int arg) { }
-        public virtual void Emit(System.Reflection.Emit.OpCode opcode, long arg) { }
-        public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con) { }
-        public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label label) { }
-        public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label[] labels) { }
-        public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.LocalBuilder local) { }
-        public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.SignatureHelper signature) { }
-        public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.FieldInfo field) { }
-        public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo meth) { }
+        public abstract System.Reflection.Emit.LocalBuilder DeclareLocal(System.Type localType, bool pinned);
+        public abstract System.Reflection.Emit.Label DefineLabel();
+        public abstract void Emit(System.Reflection.Emit.OpCode opcode);
+        public abstract void Emit(System.Reflection.Emit.OpCode opcode, byte arg);
+        public abstract void Emit(System.Reflection.Emit.OpCode opcode, double arg);
+        public abstract void Emit(System.Reflection.Emit.OpCode opcode, short arg);
+        public abstract void Emit(System.Reflection.Emit.OpCode opcode, int arg);
+        public abstract void Emit(System.Reflection.Emit.OpCode opcode, long arg);
+        public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
+        public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label label);
+        public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label[] labels);
+        public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.LocalBuilder local);
+        public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.SignatureHelper signature);
+        public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.FieldInfo field);
+        public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo meth);
         [System.CLSCompliantAttribute(false)]
         public void Emit(System.Reflection.Emit.OpCode opcode, sbyte arg) { }
-        public virtual void Emit(System.Reflection.Emit.OpCode opcode, float arg) { }
-        public virtual void Emit(System.Reflection.Emit.OpCode opcode, string str) { }
-        public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Type cls) { }
-        public virtual void EmitCall(System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo methodInfo, System.Type[]? optionalParameterTypes) { }
-        public virtual void EmitCalli(System.Reflection.Emit.OpCode opcode, System.Reflection.CallingConventions callingConvention, System.Type? returnType, System.Type[]? parameterTypes, System.Type[]? optionalParameterTypes) { }
-        public virtual void EmitCalli(System.Reflection.Emit.OpCode opcode, System.Runtime.InteropServices.CallingConvention unmanagedCallConv, System.Type? returnType, System.Type[]? parameterTypes) { }
+        public abstract void Emit(System.Reflection.Emit.OpCode opcode, float arg);
+        public abstract void Emit(System.Reflection.Emit.OpCode opcode, string str);
+        public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Type cls);
+        public abstract void EmitCall(System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo methodInfo, System.Type[]? optionalParameterTypes);
+        public abstract void EmitCalli(System.Reflection.Emit.OpCode opcode, System.Reflection.CallingConventions callingConvention, System.Type? returnType, System.Type[]? parameterTypes, System.Type[]? optionalParameterTypes);
+        public abstract void EmitCalli(System.Reflection.Emit.OpCode opcode, System.Runtime.InteropServices.CallingConvention unmanagedCallConv, System.Type? returnType, System.Type[]? parameterTypes);
         public virtual void EmitWriteLine(System.Reflection.Emit.LocalBuilder localBuilder) { }
         public virtual void EmitWriteLine(System.Reflection.FieldInfo fld) { }
         public virtual void EmitWriteLine(string value) { }
-        public virtual void EndExceptionBlock() { }
-        public virtual void EndScope() { }
-        public virtual void MarkLabel(System.Reflection.Emit.Label loc) { }
+        public abstract void EndExceptionBlock();
+        public abstract void EndScope();
+        public abstract void MarkLabel(System.Reflection.Emit.Label loc);
         public virtual void ThrowException([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] System.Type excType) { }
-        public virtual void UsingNamespace(string usingNamespace) { }
+        public abstract void UsingNamespace(string usingNamespace);
     }
     public readonly partial struct Label : System.IEquatable<System.Reflection.Emit.Label>
     {
index b8e53f4..a469865 100644 (file)
       <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\DynamicILInfo.cs" />
       <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\DynamicMethod.Mono.cs" />
       <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\FieldOnTypeBuilderInstantiation.Mono.cs" />
-      <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\ILGenerator.Mono.cs" />
       <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\LocalBuilder.Mono.cs" />
       <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\MethodOnTypeBuilderInstantiation.Mono.cs" />
       <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\MonoArrayMethod.cs" />
       <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\RuntimeEventBuilder.Mono.cs" />
       <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\RuntimeFieldBuilder.Mono.cs" />
       <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\RuntimeGenericTypeParameterBuilder.cs" />
+      <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\RuntimeILGenerator.Mono.cs" />
       <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\RuntimeMethodBuilder.Mono.cs" />
       <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\RuntimeModuleBuilder.Mono.cs" />
       <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\RuntimeParameterBuilder.Mono.cs" />
index ca10cc9..c96c0cb 100644 (file)
@@ -66,29 +66,29 @@ namespace System.Reflection.Emit
 
         public int GetTokenFor(DynamicMethod method)
         {
-            return this.method.GetILGenerator().TokenGenerator.GetToken(method, false);
+            return this.method.GetRuntimeILGenerator().TokenGenerator.GetToken(method, false);
         }
 
         public int GetTokenFor(RuntimeFieldHandle field)
         {
-            return this.method.GetILGenerator().TokenGenerator.GetToken(FieldInfo.GetFieldFromHandle(field), false);
+            return this.method.GetRuntimeILGenerator().TokenGenerator.GetToken(FieldInfo.GetFieldFromHandle(field), false);
         }
 
         public int GetTokenFor(RuntimeMethodHandle method)
         {
             MethodBase mi = MethodBase.GetMethodFromHandle(method)!;
-            return this.method.GetILGenerator().TokenGenerator.GetToken(mi, false);
+            return this.method.GetRuntimeILGenerator().TokenGenerator.GetToken(mi, false);
         }
 
         public int GetTokenFor(RuntimeTypeHandle type)
         {
             Type t = Type.GetTypeFromHandle(type)!;
-            return this.method.GetILGenerator().TokenGenerator.GetToken(t, false);
+            return this.method.GetRuntimeILGenerator().TokenGenerator.GetToken(t, false);
         }
 
         public int GetTokenFor(string literal)
         {
-            return method.GetILGenerator().TokenGenerator.GetToken(literal);
+            return method.GetRuntimeILGenerator().TokenGenerator.GetToken(literal);
         }
 
         // FIXME:
@@ -105,7 +105,7 @@ namespace System.Reflection.Emit
 
         public void SetCode(byte[]? code, int maxStackSize)
         {
-            method.GetILGenerator().SetCode(code, maxStackSize);
+            method.GetRuntimeILGenerator().SetCode(code, maxStackSize);
         }
 
         [CLSCompliantAttribute(false)]
@@ -115,7 +115,7 @@ namespace System.Reflection.Emit
             if (codeSize > 0)
                 ArgumentNullException.ThrowIfNull(code);
 
-            method.GetILGenerator().SetCode(code, codeSize, maxStackSize);
+            method.GetRuntimeILGenerator().SetCode(code, codeSize, maxStackSize);
         }
 
         // FIXME:
index 834f648..d0f8984 100644 (file)
@@ -18,7 +18,7 @@ namespace System.Reflection.Emit
         private bool _skipVisibility;
         private bool _restrictedSkipVisibility;
         private bool _initLocals;
-        private ILGenerator? _ilGenerator;
+        private RuntimeILGenerator? _ilGenerator;
         private int _nrefs;
         private object?[]? _refs;
         private IntPtr _referencedBy;
@@ -59,8 +59,12 @@ namespace System.Reflection.Emit
 
         public DynamicILInfo GetDynamicILInfo() => _dynamicILInfo ??= new DynamicILInfo(this);
 
-        public ILGenerator GetILGenerator(int streamSize) =>
-            _ilGenerator ??= new ILGenerator(Module, new DynamicMethodTokenGenerator(this), streamSize);
+        public ILGenerator GetILGenerator(int streamSize) => GetILGeneratorInternal(streamSize);
+
+        internal RuntimeILGenerator GetRuntimeILGenerator() => GetILGeneratorInternal(64);
+
+        private RuntimeILGenerator GetILGeneratorInternal(int streamSize) =>
+            _ilGenerator ??= new RuntimeILGenerator(Module, new DynamicMethodTokenGenerator(this), streamSize);
 
         public override object? Invoke(object? obj, BindingFlags invokeAttr, Binder? binder, object?[]? parameters, CultureInfo? culture)
         {
index ecfae6b..f6127e1 100644 (file)
@@ -46,7 +46,7 @@ namespace System.Reflection.Emit
     {
 #region Sync with MonoReflectionCtorBuilder in object-internals.h
         private RuntimeMethodHandle mhandle;
-        private ILGenerator? ilgen;
+        private RuntimeILGenerator? ilgen;
         internal Type[]? parameters;
         private MethodAttributes attrs;
         private MethodImplAttributes iattrs;
@@ -251,7 +251,7 @@ namespace System.Reflection.Emit
                 return ilgen;
             if (!(((attrs & (MethodAttributes.Abstract | MethodAttributes.PinvokeImpl)) == 0) && ((iattrs & (MethodImplAttributes.Runtime | MethodImplAttributes.InternalCall)) == 0)))
                 throw new InvalidOperationException();
-            ilgen = new ILGenerator(type.Module, ((RuntimeModuleBuilder)type.Module).GetTokenGenerator(), streamSize);
+            ilgen = new RuntimeILGenerator(type.Module, ((RuntimeModuleBuilder)type.Module).GetTokenGenerator(), streamSize);
             return ilgen;
         }
 
@@ -180,7 +180,7 @@ namespace System.Reflection.Emit
     }
 
     [StructLayout(LayoutKind.Sequential)]
-    public partial class ILGenerator
+    internal sealed class RuntimeILGenerator : ILGenerator
     {
         private struct LabelFixup
         {
@@ -227,7 +227,7 @@ namespace System.Reflection.Emit
         private const int defaultExceptionStackSize = 2;
 
         [DynamicDependency(nameof(token_fixups))]  // Automatically keeps all previous fields too due to StructLayout
-        internal ILGenerator(Module m, ITokenGenerator token_gen, int size)
+        internal RuntimeILGenerator(Module m, ITokenGenerator token_gen, int size)
         {
             if (size < 0)
                 size = 128;
@@ -343,7 +343,7 @@ namespace System.Reflection.Emit
             }
         }
 
-        public virtual void BeginCatchBlock(Type? exceptionType)
+        public override void BeginCatchBlock(Type? exceptionType)
         {
             if (!InExceptionBlock)
                 throw new NotSupportedException(SR.Argument_NotInExceptionBlock);
@@ -369,7 +369,7 @@ namespace System.Reflection.Emit
             //System.Console.WriteLine ("Begin catch Block: {0} {1}",exceptionType.ToString(), max_stack);
         }
 
-        public virtual void BeginExceptFilterBlock()
+        public override void BeginExceptFilterBlock()
         {
             if (!InExceptionBlock)
                 throw new NotSupportedException(SR.Argument_NotInExceptionBlock);
@@ -378,7 +378,7 @@ namespace System.Reflection.Emit
             ex_handlers![cur_block].AddFilter(code_len);
         }
 
-        public virtual Label BeginExceptionBlock()
+        public override Label BeginExceptionBlock()
         {
             //System.Console.WriteLine ("Begin Block");
             Int32Stack open_blocks = this.open_blocks ??= new Int32Stack(defaultExceptionStackSize);
@@ -400,7 +400,7 @@ namespace System.Reflection.Emit
             return ex_handlers[cur_block].end = DefineLabel();
         }
 
-        public virtual void BeginFaultBlock()
+        public override void BeginFaultBlock()
         {
             if (!InExceptionBlock)
                 throw new NotSupportedException(SR.Argument_NotInExceptionBlock);
@@ -416,7 +416,7 @@ namespace System.Reflection.Emit
             ex_handlers[cur_block].AddFault(code_len);
         }
 
-        public virtual void BeginFinallyBlock()
+        public override void BeginFinallyBlock()
         {
             if (!InExceptionBlock)
                 throw new NotSupportedException(SR.Argument_NotInExceptionBlock);
@@ -433,16 +433,10 @@ namespace System.Reflection.Emit
             ex_handlers[cur_block].AddFinally(code_len);
         }
 
-        public virtual void BeginScope()
+        public override void BeginScope()
         { }
 
-        public virtual LocalBuilder DeclareLocal(Type localType)
-        {
-            return DeclareLocal(localType, false);
-        }
-
-
-        public virtual LocalBuilder DeclareLocal(Type localType, bool pinned)
+        public override LocalBuilder DeclareLocal(Type localType, bool pinned)
         {
             ArgumentNullException.ThrowIfNull(localType);
             if (localType.IsUserType)
@@ -466,7 +460,7 @@ namespace System.Reflection.Emit
             return res;
         }
 
-        public virtual Label DefineLabel()
+        public override Label DefineLabel()
         {
             if (labels == null)
             {
@@ -484,20 +478,20 @@ namespace System.Reflection.Emit
             return new Label(num_labels++);
         }
 
-        public virtual void Emit(OpCode opcode)
+        public override void Emit(OpCode opcode)
         {
             make_room(2);
             ll_emit(opcode);
         }
 
-        public virtual void Emit(OpCode opcode, byte arg)
+        public override void Emit(OpCode opcode, byte arg)
         {
             make_room(3);
             ll_emit(opcode);
             code[code_len++] = arg;
         }
 
-        public virtual void Emit(OpCode opcode, ConstructorInfo con)
+        public override void Emit(OpCode opcode, ConstructorInfo con)
         {
             int token = token_gen.GetToken(con, true);
             make_room(6);
@@ -508,7 +502,7 @@ namespace System.Reflection.Emit
                 cur_stack -= con.GetParametersCount();
         }
 
-        public virtual void Emit(OpCode opcode, double arg)
+        public override void Emit(OpCode opcode, double arg)
         {
             make_room(10);
             ll_emit(opcode);
@@ -516,7 +510,7 @@ namespace System.Reflection.Emit
             code_len += 8;
         }
 
-        public virtual void Emit(OpCode opcode, FieldInfo field)
+        public override void Emit(OpCode opcode, FieldInfo field)
         {
             int token = token_gen.GetToken(field, true);
             make_room(6);
@@ -524,7 +518,7 @@ namespace System.Reflection.Emit
             emit_int(token);
         }
 
-        public virtual void Emit(OpCode opcode, short arg)
+        public override void Emit(OpCode opcode, short arg)
         {
             make_room(4);
             ll_emit(opcode);
@@ -532,14 +526,14 @@ namespace System.Reflection.Emit
             code_len += 2;
         }
 
-        public virtual void Emit(OpCode opcode, int arg)
+        public override void Emit(OpCode opcode, int arg)
         {
             make_room(6);
             ll_emit(opcode);
             emit_int(arg);
         }
 
-        public virtual void Emit(OpCode opcode, long arg)
+        public override void Emit(OpCode opcode, long arg)
         {
             make_room(10);
             ll_emit(opcode);
@@ -547,7 +541,7 @@ namespace System.Reflection.Emit
             code_len += 8;
         }
 
-        public virtual void Emit(OpCode opcode, Label label)
+        public override void Emit(OpCode opcode, Label label)
         {
             int tlen = target_len(opcode);
             make_room(6);
@@ -573,7 +567,7 @@ namespace System.Reflection.Emit
 
         }
 
-        public virtual void Emit(OpCode opcode, Label[] labels)
+        public override void Emit(OpCode opcode, Label[] labels)
         {
             ArgumentNullException.ThrowIfNull(labels);
 
@@ -622,7 +616,7 @@ namespace System.Reflection.Emit
             }
         }
 
-        public virtual void Emit(OpCode opcode, LocalBuilder local)
+        public override void Emit(OpCode opcode, LocalBuilder local)
         {
             ArgumentNullException.ThrowIfNull(local);
             if (local.ilgen != this)
@@ -713,7 +707,7 @@ namespace System.Reflection.Emit
             }
         }
 
-        public virtual void Emit(OpCode opcode, MethodInfo meth)
+        public override void Emit(OpCode opcode, MethodInfo meth)
         {
             ArgumentNullException.ThrowIfNull(meth);
 
@@ -744,15 +738,7 @@ namespace System.Reflection.Emit
                 cur_stack -= method.GetParametersCount();
         }
 
-        [CLSCompliant(false)]
-        public void Emit(OpCode opcode, sbyte arg)
-        {
-            make_room(3);
-            ll_emit(opcode);
-            code[code_len++] = (byte)arg;
-        }
-
-        public virtual void Emit(OpCode opcode, SignatureHelper signature)
+        public override void Emit(OpCode opcode, SignatureHelper signature)
         {
             int token = token_gen.GetToken(signature);
             make_room(6);
@@ -760,7 +746,7 @@ namespace System.Reflection.Emit
             emit_int(token);
         }
 
-        public virtual void Emit(OpCode opcode, float arg)
+        public override void Emit(OpCode opcode, float arg)
         {
             make_room(6);
             ll_emit(opcode);
@@ -768,7 +754,7 @@ namespace System.Reflection.Emit
             code_len += 4;
         }
 
-        public virtual void Emit(OpCode opcode, string str)
+        public override void Emit(OpCode opcode, string str)
         {
             int token = token_gen.GetToken(str);
             make_room(6);
@@ -776,7 +762,7 @@ namespace System.Reflection.Emit
             emit_int(token);
         }
 
-        public virtual void Emit(OpCode opcode, Type cls)
+        public override void Emit(OpCode opcode, Type cls)
         {
             make_room(6);
             ll_emit(opcode);
@@ -785,7 +771,7 @@ namespace System.Reflection.Emit
         }
 
         // FIXME: vararg methods are not supported
-        public virtual void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[]? optionalParameterTypes)
+        public override void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[]? optionalParameterTypes)
         {
             ArgumentNullException.ThrowIfNull(methodInfo);
             short value = opcode.Value;
@@ -807,7 +793,7 @@ namespace System.Reflection.Emit
             Emit(opcode, methodInfo);
         }
 
-        public virtual void EmitCalli(OpCode opcode, CallingConvention unmanagedCallConv, Type? returnType, Type[]? parameterTypes)
+        public override void EmitCalli(OpCode opcode, CallingConvention unmanagedCallConv, Type? returnType, Type[]? parameterTypes)
         {
             // GetMethodSigHelper expects a ModuleBuilder or null, and module might be
             // a normal module when using dynamic methods.
@@ -815,7 +801,7 @@ namespace System.Reflection.Emit
             Emit(opcode, helper);
         }
 
-        public virtual void EmitCalli(OpCode opcode, CallingConventions callingConvention, Type returnType, Type[]? parameterTypes, Type[]? optionalParameterTypes)
+        public override void EmitCalli(OpCode opcode, CallingConventions callingConvention, Type? returnType, Type[]? parameterTypes, Type[]? optionalParameterTypes)
         {
             if (optionalParameterTypes != null)
                 throw new NotImplementedException();
@@ -824,46 +810,7 @@ namespace System.Reflection.Emit
             Emit(opcode, helper);
         }
 
-        private const string ConsoleTypeFullName = "System.Console, System.Console";
-
-        public virtual void EmitWriteLine(FieldInfo fld)
-        {
-            ArgumentNullException.ThrowIfNull(fld);
-
-            // The MS implementation does not check for valuetypes here but it
-            // should. Also, it should check that if the field is not static,
-            // then it is a member of this type.
-            if (fld.IsStatic)
-                Emit(OpCodes.Ldsfld, fld);
-            else
-            {
-                Emit(OpCodes.Ldarg_0);
-                Emit(OpCodes.Ldfld, fld);
-            }
-            Type consoleType = Type.GetType(ConsoleTypeFullName, throwOnError: true)!;
-            Emit(OpCodes.Call, consoleType.GetMethod("WriteLine", new Type[1] { fld.FieldType })!);
-        }
-
-        public virtual void EmitWriteLine(LocalBuilder localBuilder)
-        {
-            ArgumentNullException.ThrowIfNull(localBuilder);
-            if (localBuilder.LocalType is TypeBuilder)
-                throw new NotSupportedException(SR.NotSupported_OutputStreamUsingTypeBuilder);
-            // The MS implementation does not check for valuetypes here but it
-            // should.
-            Emit(OpCodes.Ldloc, localBuilder);
-            Type consoleType = Type.GetType(ConsoleTypeFullName, throwOnError: true)!;
-            Emit(OpCodes.Call, consoleType.GetMethod("WriteLine", new Type[1] { localBuilder.LocalType })!);
-        }
-
-        public virtual void EmitWriteLine(string value)
-        {
-            Emit(OpCodes.Ldstr, value);
-            Type consoleType = Type.GetType(ConsoleTypeFullName, throwOnError: true)!;
-            Emit(OpCodes.Call, consoleType.GetMethod("WriteLine", new Type[1] { typeof(string) })!);
-        }
-
-        public virtual void EndExceptionBlock()
+        public override void EndExceptionBlock()
         {
             if (!InExceptionBlock)
                 throw new NotSupportedException(SR.Argument_NotInExceptionBlock);
@@ -879,10 +826,10 @@ namespace System.Reflection.Emit
                 cur_block = open_blocks.Peek()!;
         }
 
-        public virtual void EndScope()
+        public override void EndScope()
         { }
 
-        public virtual void MarkLabel(Label loc)
+        public override void MarkLabel(Label loc)
         {
             if (loc.m_label < 0 || loc.m_label >= num_labels)
                 throw new System.ArgumentException(SR.Argument_InvalidLabel);
@@ -893,21 +840,9 @@ namespace System.Reflection.Emit
                 cur_stack = labels[loc.m_label].maxStack;
         }
 
-        public virtual void ThrowException([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type excType)
-        {
-            ArgumentNullException.ThrowIfNull(excType);
-            if (!((excType == typeof(Exception)) ||
-                   excType.IsSubclassOf(typeof(Exception))))
-                throw new ArgumentException(SR.Argument_NotExceptionType, nameof(excType));
-            ConstructorInfo? ctor = excType.GetConstructor(Type.EmptyTypes);
-            if (ctor == null)
-                throw new ArgumentException(SR.Arg_NoDefCTorWithoutTypeName, nameof(excType));
-            Emit(OpCodes.Newobj, ctor);
-            Emit(OpCodes.Throw);
-        }
 
         // FIXME: "Not implemented"
-        public virtual void UsingNamespace(string usingNamespace)
+        public override void UsingNamespace(string usingNamespace)
         {
             throw new NotImplementedException();
         }
@@ -955,7 +890,7 @@ namespace System.Reflection.Emit
 
         internal ITokenGenerator TokenGenerator => token_gen;
 
-        public virtual int ILOffset => code_len;
+        public override int ILOffset => code_len;
     }
 
     internal struct SequencePoint
index 88996e0..8e4503c 100644 (file)
@@ -53,7 +53,7 @@ namespace System.Reflection.Emit
         private string name;
         private int table_idx;
         private byte[]? code;
-        private ILGenerator? ilgen;
+        private RuntimeILGenerator? ilgen;
         private RuntimeTypeBuilder type;
         internal ParameterBuilder[]? pinfo;
         private CustomAttributeBuilder[]? cattrs;
@@ -321,7 +321,7 @@ namespace System.Reflection.Emit
                 throw new InvalidOperationException(SR.InvalidOperation_ShouldNotHaveMethodBody);
             if (ilgen != null)
                 return ilgen;
-            ilgen = new ILGenerator(type.Module, ((RuntimeModuleBuilder)type.Module).GetTokenGenerator(), size);
+            ilgen = new RuntimeILGenerator(type.Module, ((RuntimeModuleBuilder)type.Module).GetTokenGenerator(), size);
             return ilgen;
         }