Last active
March 30, 2020 05:45
-
-
Save rcook/1bbacb700b49fd733d0c to your computer and use it in GitHub Desktop.
Instrumenting IL generation in Mono's C# compiler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 4ba47528a583a47f38c2d9f1f9bff71b3b6a37e2 Mon Sep 17 00:00:00 2001 | |
From: Richard Cook <[email protected]> | |
Date: Fri, 1 Oct 2010 13:17:00 -0700 | |
Subject: [PATCH] Emit custom prologue and epilogue code and top and bottom of each method body | |
--- | |
mcs/mcs/dmcs.csproj | 3 ++- | |
mcs/mcs/gmcs.csproj | 3 ++- | |
mcs/mcs/gmcs.exe.sources | 1 + | |
mcs/mcs/instrumentation.cs | 39 +++++++++++++++++++++++++++++++++++++++ | |
mcs/mcs/method.cs | 4 +++- | |
mcs/mcs/pending.cs | 1 + | |
mcs/mcs/statement.cs | 6 +++++- | |
7 files changed, 53 insertions(+), 4 deletions(-) | |
create mode 100644 mcs/mcs/instrumentation.cs | |
diff --git a/mcs/mcs/dmcs.csproj b/mcs/mcs/dmcs.csproj | |
index 154cad4..b8aef21 100644 | |
--- a/mcs/mcs/dmcs.csproj | |
+++ b/mcs/mcs/dmcs.csproj | |
@@ -100,6 +100,7 @@ | |
<Compile Include="flowanalysis.cs"> | |
</Compile> | |
<Compile Include="generic.cs" /> | |
+ <Compile Include="instrumentation.cs" /> | |
<Compile Include="iterators.cs"> | |
</Compile> | |
<Compile Include="literal.cs"> | |
@@ -151,4 +152,4 @@ | |
<Target Name="AfterBuild"> | |
</Target> | |
--> | |
-</Project> | |
\ No newline at end of file | |
+</Project> | |
diff --git a/mcs/mcs/gmcs.csproj b/mcs/mcs/gmcs.csproj | |
index 612d21a..357800e 100644 | |
--- a/mcs/mcs/gmcs.csproj | |
+++ b/mcs/mcs/gmcs.csproj | |
@@ -74,6 +74,7 @@ | |
<Compile Include="expression.cs" /> | |
<Compile Include="flowanalysis.cs" /> | |
<Compile Include="generic.cs" /> | |
+ <Compile Include="instrumentation.cs" /> | |
<Compile Include="iterators.cs" /> | |
<Compile Include="literal.cs" /> | |
<Compile Include="location.cs" /> | |
@@ -109,4 +110,4 @@ | |
<Target Name="AfterBuild"> | |
</Target> | |
--> | |
-</Project> | |
\ No newline at end of file | |
+</Project> | |
diff --git a/mcs/mcs/gmcs.exe.sources b/mcs/mcs/gmcs.exe.sources | |
index 03738c5..59b440c 100644 | |
--- a/mcs/mcs/gmcs.exe.sources | |
+++ b/mcs/mcs/gmcs.exe.sources | |
@@ -26,6 +26,7 @@ field.cs | |
flowanalysis.cs | |
generic.cs | |
import.cs | |
+instrumentation.cs | |
iterators.cs | |
lambda.cs | |
linq.cs | |
diff --git a/mcs/mcs/instrumentation.cs b/mcs/mcs/instrumentation.cs | |
new file mode 100644 | |
index 0000000..6956f76 | |
--- /dev/null | |
+++ b/mcs/mcs/instrumentation.cs | |
@@ -0,0 +1,39 @@ | |
+using System; | |
+using System.Reflection; | |
+using System.Reflection.Emit; | |
+using Mono.CSharp; | |
+ | |
+namespace Instrumentation | |
+{ | |
+ internal static class Helpers | |
+ { | |
+ internal static void EmitPrologue(ILGenerator ilGenerator, string methodName) | |
+ { | |
+ EmitConsoleWriteLine(ilGenerator, string.Format("PROLOGUE: {0}", methodName)); | |
+ } | |
+ | |
+ internal static void EmitEpilogue(EmitContext emitContext) | |
+ { | |
+ if (emitContext.MemberContext.CurrentMemberDefinition is Method) | |
+ { | |
+ ILGenerator ilGenerator = emitContext.ig; | |
+ string methodName = emitContext.MemberContext.CurrentMemberDefinition.Name; | |
+ EmitConsoleWriteLine(ilGenerator, string.Format("EPILOGUE: {0}", methodName)); | |
+ } | |
+ } | |
+ | |
+ private static void EmitConsoleWriteLine(ILGenerator ilGenerator, string message) | |
+ { | |
+ ilGenerator.Emit(OpCodes.Ldstr, message); | |
+ MethodInfo writeLineMethod = typeof(Console).GetMethod( | |
+ "WriteLine", | |
+ BindingFlags.Public | BindingFlags.Static, | |
+ null, | |
+ new Type[] {typeof(string)}, | |
+ null | |
+ ); | |
+ ilGenerator.Emit(OpCodes.Call, writeLineMethod); | |
+ } | |
+ } | |
+} | |
+ | |
diff --git a/mcs/mcs/method.cs b/mcs/mcs/method.cs | |
index 6ae3e78..7a33445 100644 | |
--- a/mcs/mcs/method.cs | |
+++ b/mcs/mcs/method.cs | |
@@ -1833,7 +1833,9 @@ namespace Mono.CSharp { | |
builder = container.TypeBuilder.DefineMethod ( | |
method_name, flags, method.CallingConventions, | |
return_type, p_types); | |
- return; | |
+ | |
+ Instrumentation.Helpers.EmitPrologue(builder.GetILGenerator(), method_name); | |
+ return; | |
} | |
// | |
diff --git a/mcs/mcs/pending.cs b/mcs/mcs/pending.cs | |
index 23d80df..a168b6a 100644 | |
--- a/mcs/mcs/pending.cs | |
+++ b/mcs/mcs/pending.cs | |
@@ -347,6 +347,7 @@ namespace Mono.CSharp { | |
ParameterReference.EmitLdArg (ec, i); | |
ec.Emit (OpCodes.Call, base_method); | |
+Console.WriteLine("pending.cs"); | |
ec.Emit (OpCodes.Ret); | |
container.TypeBuilder.DefineMethodOverride (proxy, (MethodInfo) iface_method.GetMetaInfo ()); | |
diff --git a/mcs/mcs/statement.cs b/mcs/mcs/statement.cs | |
index 4a3c42f..17611cf 100644 | |
--- a/mcs/mcs/statement.cs | |
+++ b/mcs/mcs/statement.cs | |
@@ -794,8 +794,10 @@ namespace Mono.CSharp { | |
if (unwind_protect) | |
ec.Emit (OpCodes.Leave, ec.ReturnLabel); | |
- else | |
+ else { | |
+ Instrumentation.Helpers.EmitEpilogue(ec); | |
ec.Emit (OpCodes.Ret); | |
+ } | |
} | |
void Error_ReturnFromIterator (ResolveContext rc) | |
@@ -2919,6 +2921,7 @@ namespace Mono.CSharp { | |
if (ec.return_value != null) { | |
ec.Emit (OpCodes.Ldloc, ec.return_value); | |
+ Instrumentation.Helpers.EmitEpilogue(ec); | |
ec.Emit (OpCodes.Ret); | |
} else { | |
// | |
@@ -2937,6 +2940,7 @@ namespace Mono.CSharp { | |
if (ec.HasReturnLabel || !unreachable) { | |
if (ec.ReturnType != TypeManager.void_type) | |
ec.Emit (OpCodes.Ldloc, ec.TemporaryReturn ()); | |
+ Instrumentation.Helpers.EmitEpilogue(ec); | |
ec.Emit (OpCodes.Ret); | |
} | |
} | |
-- | |
1.7.0.4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The MIT License (MIT) | |
Copyright (c) 2010 Richard Cook | |
Permission is hereby granted, free of charge, to any person obtaining a copy of | |
this software and associated documentation files (the "Software"), to deal in | |
the Software without restriction, including without limitation the rights to | |
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | |
the Software, and to permit persons to whom the Software is furnished to do so, | |
subject to the following conditions: | |
The above copyright notice and this permission notice shall be included in all | |
copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | |
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | |
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | |
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment