-
-
Save arlm/60a1a8a10166e91c800436beda1253d1 to your computer and use it in GitHub Desktop.
Shows how to use the prototype inline IL ASM with Roslyn
This file contains hidden or 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
using System; | |
using System.IO; | |
using System.Runtime.CompilerServices; | |
namespace System.Runtime.CompilerServices | |
{ | |
[AttributeUsage(AttributeTargets.Method)] | |
internal class CompilerIntrinsicAttribute : Attribute { } | |
} | |
class Program | |
{ | |
[CompilerIntrinsic] | |
static void il(params object[] args) {} // cannot use extern for the prototype, as it fails when loading the type without a DllImport | |
[CompilerIntrinsic] | |
static T il<T>(params object[] args) { return default(T); } // cannot use extern for the prototype, as it fails when loading the type without a DllImport | |
struct Vector3 | |
{ | |
public float X; | |
public float Y; | |
public float Z; | |
} | |
public static int SizeOf<T>() where T : struct | |
{ | |
// sizeof with generic! | |
return il<int>(@sizeof, T); | |
} | |
public static void TryBindMethod(string[] args) | |
{ | |
Console.WriteLine($"method call: TryBindMethod with {args.Length} arguments"); | |
} | |
public static void Main(string[] args) | |
{ | |
// ----------------------- | |
// method call | |
// ----------------------- | |
// Console.WriteLine(sizeof(Vector3) + 4) | |
// IL_0000: nop | |
// IL_0001: sizeof Program/Vector3 | |
// IL_0007: ldc.i4.4 | |
// IL_0008: add | |
// IL_0009: call void [mscorlib]System.Console::WriteLine(int32) | |
il(nop); // just to show that we can output nop, not really instesting though! | |
il(@sizeof, Vector3); // use of @ as sizeof is a keyword | |
il(ldc.i4_4); | |
il(add); | |
il(call, Console.WriteLine(default(int))); // we define the signature with a fake method call | |
// ----------------------- | |
// load from local var | |
// ----------------------- | |
var myLocalArgs = args; | |
il(ldloc, myLocalArgs); | |
il(call, TryBindMethod); | |
// ----------------------- | |
// store to local var | |
// ----------------------- | |
int x; | |
il(@sizeof, Vector3); // use of @ as sizeof is a keyword | |
il(stloc, x); | |
Console.WriteLine("sizeof<Vector3> stored in local var: " + x); | |
// ----------------------- | |
// sizeof with generic | |
// ----------------------- | |
Console.WriteLine("Sizeof<T> with Vector3: " + SizeOf<Vector3>()); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment