Last active
June 2, 2024 09:13
-
-
Save kekyo/bc8e411b846c98d2f2ae7b839ef77fea to your computer and use it in GitHub Desktop.
Extract CIL opcodes and makes relation chibias-cil opcode naming both Reflection.Emit and Cecil.
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.Linq; | |
namespace ConsoleApp1; | |
class Program | |
{ | |
static void GenerateReflectionEmit() | |
{ | |
var emitOpCodes = | |
typeof(System.Reflection.Emit.OpCodes).GetFields(). | |
Where(field => field is | |
{ | |
IsPublic: true, IsStatic: true, IsInitOnly: true, | |
FieldType.FullName: "System.Reflection.Emit.OpCode" | |
}). | |
Select(field => (fieldName: field.Name, opCode: (System.Reflection.Emit.OpCode)field.GetValue(null)!)). | |
Where(entry => entry.opCode.OpCodeType != System.Reflection.Emit.OpCodeType.Nternal). | |
OrderBy(entry => entry.opCode.Value). | |
Select(entry => (entry.fieldName, name: entry.opCode.Name!.Replace('_', '.').TrimEnd('.').ToLowerInvariant())). | |
ToArray(); | |
Console.WriteLine("namespace chibicc.toolchain.Internal;"); | |
Console.WriteLine(); | |
Console.WriteLine("internal static class ReflectionEmitDefinition"); | |
Console.WriteLine("{"); | |
Console.WriteLine(" public static System.Collections.Generic.Dictionary<string, System.Reflection.Emit.OpCode> GetOpCodes() =>"); | |
Console.WriteLine(" new(System.StringComparer.OrdinalIgnoreCase)"); | |
Console.WriteLine(" {"); | |
foreach (var entry in emitOpCodes) | |
{ | |
Console.WriteLine( | |
$" {{ \"{entry.name}\", System.Reflection.Emit.OpCodes.{entry.fieldName} }},"); | |
} | |
Console.WriteLine(" };"); | |
Console.WriteLine("}"); | |
} | |
static void GenerateCecil() | |
{ | |
var emitOpCodeBytes = | |
typeof(System.Reflection.Emit.OpCodes).GetFields(). | |
Where(field => field is | |
{ | |
IsPublic: true, IsStatic: true, IsInitOnly: true, | |
FieldType.FullName: "System.Reflection.Emit.OpCode" | |
}). | |
Select(field => (fieldName: field.Name, opCode: (System.Reflection.Emit.OpCode)field.GetValue(null)!)). | |
Where(entry => entry.opCode.OpCodeType != System.Reflection.Emit.OpCodeType.Nternal). | |
ToDictionary( | |
entry => entry.opCode.Value, | |
entry => (entry.fieldName, name: entry.opCode.Name!.Replace('_', '.').TrimEnd('.').ToLowerInvariant())); | |
var cecilOpCodes = typeof(Mono.Cecil.Cil.OpCodes).GetFields(). | |
Where(field => | |
field.IsPublic && field.IsStatic && field.IsInitOnly && | |
field.FieldType.FullName == "Mono.Cecil.Cil.OpCode"). | |
Select(field => | |
{ | |
var opCode = (Mono.Cecil.Cil.OpCode)field.GetValue(null)!; | |
if (emitOpCodeBytes.TryGetValue(opCode.Value, out var entry)) | |
{ | |
return (fieldName: field.Name, opCode, name: entry.name); | |
} | |
else | |
{ | |
return (null!, default, null!); | |
} | |
}). | |
Where(entry => entry.name != null && entry.opCode.OpCodeType != Mono.Cecil.Cil.OpCodeType.Nternal). | |
OrderBy(entry => entry.opCode.Value). | |
Select(entry => (entry.fieldName, name: entry.name)). | |
ToArray(); | |
Console.WriteLine("namespace chibild.Internal;"); | |
Console.WriteLine(); | |
Console.WriteLine("internal static class CecilDefinition"); | |
Console.WriteLine("{"); | |
Console.WriteLine(" public static System.Collections.Generic.Dictionary<string, Mono.Cecil.Cil.OpCode> GetOpCodes() =>"); | |
Console.WriteLine(" new(System.StringComparer.OrdinalIgnoreCase)"); | |
Console.WriteLine(" {"); | |
foreach (var entry in cecilOpCodes) | |
{ | |
Console.WriteLine( | |
$" {{ \"{entry.name}\", Mono.Cecil.Cil.OpCodes.{entry.fieldName} }},"); | |
} | |
Console.WriteLine(" };"); | |
Console.WriteLine("}"); | |
} | |
static void Main(string[] args) | |
{ | |
GenerateReflectionEmit(); | |
GenerateCecil(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment