Created
May 25, 2016 03:08
-
-
Save xoofx/9d6a1522c642bbcfef7c420351b1d97d to your computer and use it in GitHub Desktop.
Shows how to use the prototype inline IL ASM with Roslyn
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
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