用于将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 | ✅ |