用于将MSIL编译到C++/MacroCode的AOT编译器。
- 打开sln,以RTCLI.AOTCompiler为启动项目;
- usage: RTCLI.AOTCompiler.exe <output_path> <assembly_paths>;
- 内置了一个TestCase项目进行开发前期代码生成测试,在调试选项中为RTCLI.AOTCompiler附加调试参数$(SolutionDir)RTCLI.Generated $(SolutionDir)RTCLI.TestCase/bin/Debug/netstandardX.X/RTCLI.TestCase.dll;
- 代码会被生成在./RTCLI.CXXTest文件夹下.
- 确保您的环境具有CMake(Version >= 3.19.0);
- 运行时仓库:RTCLI.Runtime;
- 打开运行时仓库,运行./gen_${YourIDE}.bat,此时Solution会在/build下被生成;
- 运行./install.bat进行安装,需要管理员权限.
- 打开RTCLI.CXXTest文件夹,运行./gen_${YourIDE}.bat,此时Solution会在/build下被生成;
- 打开Solution,选择对应的Test项目运行即可。
- 默认使用netstandard2.1的标准meta文件
source:
public static void Test()
{
String nullStr = null;
String str = "Static String";
System.Console.WriteLine(str);
System.Console.WriteLine(str.Length);
String lowerStr = str.ToLower();
System.Console.Write("ToLower: ");
System.Console.WriteLine(lowerStr);
}generated:
RTCLI::System::Void RTCLI::TestCase::TestString::Test()
{
RTCLI::TRef<RTCLI::System::String> v0 = RTCLI::null;
RTCLI::TRef<RTCLI::System::String> v1 = RTCLI::null;
RTCLI::TRef<RTCLI::System::String> v2 = RTCLI::null;
// IL_0000: nop
IL_0000: RTCLI::nop();
// IL_0001: ldnull
IL_0001: auto& s0 = RTCLI::null;
// IL_0002: stloc.0
IL_0002: v0 = s0;
// IL_0003: ldstr \"Static String\"
IL_0003: RTCLI::System::String s1 = RTCLI_NATIVE_STRING("Static String");
// IL_0008: stloc.1
IL_0008: v1 = s1;
// IL_0009: ldloc.1
IL_0009: auto& s2 = v1.Get();
// IL_000a: call System.Void System.Console::WriteLine(System.String)
IL_000a: RTCLI::System::Console::WriteLine(s2);
// IL_000f: nop
IL_000f: RTCLI::nop();
// IL_0010: ldloc.1
IL_0010: auto& s3 = v1.Get();
// IL_0011: callvirt System.Int32 System.String::get_Length()
IL_0011: auto s4 = ((RTCLI::System::String&)s3).get_Length();
// IL_0016: call System.Void System.Console::WriteLine(System.Int32)
IL_0016: RTCLI::System::Console::WriteLine(s4);
// IL_001b: nop
IL_001b: RTCLI::nop();
// IL_001c: ldloc.1
IL_001c: auto& s5 = v1.Get();
// IL_001d: callvirt System.String System.String::ToLower()
IL_001d: auto s6 = ((RTCLI::System::String&)s5).ToLower();
// IL_0022: stloc.2
IL_0022: v2 = s6;
// IL_0023: ldstr \"ToLower: \"
IL_0023: RTCLI::System::String s7 = RTCLI_NATIVE_STRING("ToLower: ");
// IL_0028: call System.Void System.Console::Write(System.String)
IL_0028: RTCLI::System::Console::Write(s7);
// IL_002d: nop
IL_002d: RTCLI::nop();
// IL_002e: ldloc.2
IL_002e: auto& s8 = v2.Get();
// IL_002f: call System.Void System.Console::WriteLine(System.String)
IL_002f: RTCLI::System::Console::WriteLine(s8);
// IL_0034: nop
IL_0034: RTCLI::nop();
// IL_0035: ret
IL_0035: return ;
}| OpCode | Binary | CXXCvt | CXXRuntime | Test |
|---|---|---|---|---|
| add | 0x58 | ✅ | ✅ | |
| add.ovf | 0xd6 | ✅ | ❗ | |
| add.ovf.un | 0xd7 | ✅ | ❗ | |
| and | 0x5f | ✅ | ||
| arglist | 0xfe00 | |||
| beq | 0x3b | ✅ | ||
| beq.s | 0x2e | ✅ | ||
| bge | 0x3c | ✅ | ||
| bge.s | 0x2f | ✅ | ||
| bge.un | 0x41 | ✅ | ||
| bge.un.s | 0x34 | ✅ | ||
| bgt | 0x3d | ✅ | ||
| bgt.s | 0x30 | ✅ | ||
| bgt.un | 0x42 | ✅ | ||
| bgt.un.s | 0x35 | ✅ | ||
| ble | 0x3e | ✅ | ||
| ble.s | 0x31 | ✅ | ||
| ble.un | 0x43 | ✅ | ||
| ble.un.s | 0x36 | ✅ | ||
| blt | 0x3f | ✅ | ||
| blt.s | 0x32 | ✅ | ||
| blt.un | 0x44 | ✅ | ||
| blt.un.s | 0x37 | ✅ | ||
| bne.un | 0x40 | ✅ | ||
| bne.un.s | 0x33 | ✅ | ||
| box | 0x8c | |||
| br | 0x38 | ✅ | 🔷 | |
| br.s | 0x2b | ✅ | 🔷 | |
| break | 0x1 | |||
| brfalse | 0x39 | ✅ | 🔷 | |
| brfalse.s | 0x2c | ✅ | 🔷 | |
| brtrue | 0x3a | ✅ | 🔷 | |
| brtrue.s | 0x2d | ✅ | 🔷 | |
| call | 0x28 | ✅ | 🔷 | |
| calli | 0x29 | |||
| callvirt | 0x6f | ✅ | 🔷 | |
| castclass | 0x74 | ✅ | ||
| ceq | 0xfe01 | ✅ | ||
| cgt | 0xfe02 | ✅ | ✅ | |
| cgt.un | 0xfe03 | ✅ | ✅ | |
| ckfinite | 0xc3 | ✅ | ||
| clt | 0xfe04 | ✅ | ||
| clt.un | 0xfe05 | ✅ | ||
| constrained | 0xfe16 | |||
| conv.i | 0xd3 | |||
| conv.i1 | 0x67 | |||
| conv.i2 | 0x68 | |||
| conv.i4 | 0x69 | |||
| conv.i8 | 0x6a | |||
| conv.ovf.i | 0xd4 | |||
| conv.ovf.i.un | 0x8a | |||
| conv.ovf.i1 | 0xb3 | |||
| conv.ovf.i1.un | 0x82 | |||
| conv.ovf.i2 | 0xb5 | |||
| conv.ovf.i2.un | 0x83 | |||
| conv.ovf.i4 | 0xb7 | |||
| conv.ovf.i4.un | 0x84 | |||
| conv.ovf.i8 | 0xb9 | |||
| conv.ovf.i8.un | 0x85 | |||
| conv.ovf.u | 0xd5 | |||
| conv.ovf.u.un | 0x8b | |||
| conv.ovf.u1 | 0xb4 | |||
| conv.ovf.u1.un | 0x86 | |||
| conv.ovf.u2 | 0xb6 | |||
| conv.ovf.u2.un | 0x87 | |||
| conv.ovf.u4 | 0xb8 | |||
| conv.ovf.u4.un | 0x88 | |||
| conv.ovf.u8 | 0xba | |||
| conv.ovf.u8.un | 0x89 | |||
| conv.r.un | 0x76 | |||
| conv.r4 | 0x6b | |||
| conv.r8 | 0x6c | |||
| conv.u | 0xe0 | |||
| conv.u1 | 0xd2 | |||
| conv.u2 | 0xd1 | |||
| conv.u4 | 0x6d | |||
| conv.u8 | 0x6e | |||
| cpblk | 0xfe17 | ✅ | ||
| cpobj | 0x70 | ✅ | ||
| div | 0x5b | ✅ | ||
| div.un | 0x5c | ✅ | ||
| dup | 0x25 | ✅ | ||
| endfilter | 0xfe11 | |||
| endfinally | 0xdc | |||
| initblk | 0xfe18 | ✅ | ||
| initobj | 0xfe15 | ✅ | ||
| isinst | 0x75 | ✅ | ||
| jmp | 0x27 | 🔷 | ||
| ldarg | 0xfe09 | ✅ | 🔷 | |
| ldarg.0 | 0x2 | ✅ | 🔷 | |
| ldarg.1 | 0x3 | ✅ | 🔷 | |
| ldarg.2 | 0x4 | ✅ | 🔷 | |
| ldarg.3 | 0x5 | ✅ | 🔷 | |
| ldarg.s | 0xe | ✅ | 🔷 | |
| ldarga | 0xfe0a | ✅ | 🔷 | |
| ldarga.s | 0xf | ✅ | 🔷 | |
| ldc.i4 | 0x20 | ✅ | ||
| ldc.i4.0 | 0x16 | ✅ | ||
| ldc.i4.1 | 0x17 | ✅ | ||
| ldc.i4.2 | 0x18 | ✅ | ||
| ldc.i4.3 | 0x19 | ✅ | ||
| ldc.i4.4 | 0x1a | ✅ | ||
| ldc.i4.5 | 0x1b | ✅ | ||
| ldc.i4.6 | 0x1c | ✅ | ||
| ldc.i4.7 | 0x1d | ✅ | ||
| ldc.i4.8 | 0x1e | ✅ | ||
| ldc.i4.m1 | 0x15 | ✅ | ||
| ldc.i4.s | 0x1f | ✅ | ||
| ldc.i8 | 0x21 | ✅ | ||
| ldc.r4 | 0x22 | ✅ | ||
| ldc.r8 | 0x23 | ✅ | ||
| ldelem.any | 0xa3 | ✅ | ||
| ldelem.i | 0x97 | ✅ | ||
| ldelem.i1 | 0x90 | ✅ | ||
| ldelem.i2 | 0x92 | ✅ | ||
| ldelem.i4 | 0x94 | ✅ | ||
| ldelem.i8 | 0x96 | ✅ | ||
| ldelem.r4 | 0x98 | ✅ | ||
| ldelem.r8 | 0x99 | ✅ | ||
| ldelem.ref | 0x9a | ✅ | ||
| ldelem.u1 | 0x91 | ✅ | ||
| ldelem.u2 | 0x93 | ✅ | ||
| ldelem.u4 | 0x95 | ✅ | ||
| ldelema | 0x8f | ✅ | ||
| ldfld | 0x7b | ✅ | ||
| ldflda | 0x7c | ✅ | ||
| ldftn | 0xfe06 | ✅ | ||
| ldind.i | 0x4d | ✅ | ||
| ldind.i1 | 0x46 | ✅ | ||
| ldind.i2 | 0x48 | ✅ | ||
| ldind.i4 | 0x4a | ✅ | ||
| ldind.i8 | 0x4c | ✅ | ||
| ldind.r4 | 0x4e | ✅ | ||
| ldind.r8 | 0x4f | ✅ | ||
| ldind.ref | 0x50 | ✅ | ||
| ldind.u1 | 0x47 | ✅ | ||
| ldind.u2 | 0x49 | ✅ | ||
| ldind.u4 | 0x4b | ✅ | ||
| ldlen | 0x8e | ✅ | ||
| ldloc | 0xfe0c | ✅ | 🔷 | |
| ldloc.0 | 0x6 | ✅ | 🔷 | |
| ldloc.1 | 0x7 | ✅ | 🔷 | |
| ldloc.2 | 0x8 | ✅ | 🔷 | |
| ldloc.3 | 0x9 | ✅ | 🔷 | |
| ldloc.s | 0x11 | ✅ | 🔷 | |
| ldloca | 0xfe0d | ✅ | 🔷 | |
| ldloca.s | 0x12 | ✅ | 🔷 | |
| ldnull | 0x14 | ✅ | ||
| ldobj | 0x71 | ✅ | ||
| ldsfld | 0x7e | ✅ | ||
| ldsflda | 0x7f | ✅ | ||
| ldstr | 0x72 | ✅ | ||
| ldtoken | 0xd0 | |||
| ldvirtftn | 0xfe07 | |||
| leave | 0xdd | ✅ | ||
| leave.s | 0xde | ✅ | ||
| localloc | 0xfe0f | |||
| mkrefany | 0xc6 | |||
| mul | 0x5a | ✅ | ||
| mul.ovf | 0xd8 | ✅ | ||
| mul.ovf.un | 0xd9 | ✅ | ||
| neg | 0x65 | ✅ | ||
| newarr | 0x8d | ✅ | ||
| newobj | 0x73 | ✅ | ❗ | |
| no | 0xfe19 | |||
| nop | 0x0 | ✅ | ✅ | |
| not | 0x66 | ✅ | ||
| or | 0x60 | ✅ | ||
| pop | 0x26 | ✅ | ||
| readonly | 0xfe1e | |||
| refanytype | 0xfe1d | |||
| refanyval | 0xc2 | |||
| rem | 0x5d | ✅ | ||
| rem.un | 0x5e | ✅ | ||
| ret | 0x2a | ✅ | 🔷 | |
| rethrow | 0xfe1a | |||
| shl | 0x62 | ✅ | ||
| shr | 0x63 | ✅ | ||
| shr.un | 0x64 | ✅ | ||
| sizeof | 0xfe1c | ✅ | ||
| starg | 0xfe0b | ✅ | 🔷 | |
| starg.s | 0x10 | ✅ | 🔷 | |
| stelem.any | 0xa4 | ✅ | ||
| stelem.i | 0x9b | ✅ | ||
| stelem.i1 | 0x9c | ✅ | ||
| stelem.i2 | 0x9d | ✅ | ||
| stelem.i4 | 0x9e | ✅ | ||
| stelem.i8 | 0x9f | ✅ | ||
| stelem.r4 | 0xa0 | ✅ | ||
| stelem.r8 | 0xa1 | ✅ | ||
| stelem.ref | 0xa2 | ✅ | ||
| stfld | 0x7d | ✅ | 🔷 | |
| stind.i | 0xdf | ✅ | ||
| stind.i1 | 0x52 | ✅ | ||
| stind.i2 | 0x53 | ✅ | ||
| stind.i4 | 0x54 | ✅ | ||
| stind.i8 | 0x55 | ✅ | ||
| stind.r4 | 0x56 | ✅ | ||
| stind.r8 | 0x57 | ✅ | ||
| stind.ref | 0x51 | ✅ | ||
| stloc | 0xfe0e | ✅ | ||
| stloc.0 | 0xa | ✅ | ||
| stloc.1 | 0xb | ✅ | ||
| stloc.2 | 0xc | ✅ | ||
| stloc.3 | 0xd | ✅ | ||
| stloc.s | 0x13 | ✅ | ||
| stobj | 0x81 | ✅ | ||
| stsfld | 0x80 | ✅ | 🔷 | |
| sub | 0x59 | ✅ | ||
| sub.ovf | 0xda | ✅ | ||
| sub.ovf.un | 0xdb | ✅ | ||
| switch | 0x45 | |||
| tail | 0xfe14 | ✅ | ||
| throw | 0x7a | |||
| unaligned | 0xfe12 | |||
| unbox | 0x79 | |||
| unbox.any | 0xa5 | |||
| volatile | 0xfe13 | |||
| xor | 0x61 | ✅ |