diff --git a/README.ja.md b/README.ja.md index 83310ab..c9e169c 100644 --- a/README.ja.md +++ b/README.ja.md @@ -49,7 +49,7 @@ $ dotnet tool install -g chibias-cli ```bash $ chibias -chibias [0.26.0,net6.0] [...] +chibias [0.41.0,net6.0] [...] This is the CIL assembler, part of chibicc-cil project. https://github.com/kekyo/chibias-cil Copyright (c) Kouji Matsui @@ -60,7 +60,9 @@ usage: chibias [options] [ ...] -c, --dll Produce dll assembly --exe Produce executable assembly (defaulted) --winexe Produce Windows executable assembly - -r Reference assembly path + -a AppHost template path + -L Reference assembly base path + -l Reference assembly name -g, -g2 Produce embedded debug symbol (defaulted) -g1 Produce portable debug symbol file -gm Produce mono debug symbol file @@ -68,7 +70,7 @@ usage: chibias [options] [ ...] -g0 Omit debug symbol file -O, -O1 Apply optimization -O0 Disable optimization (defaulted) - -s Suppress runtime configuration file + -p CoreCLR rollforward configuration [Major|Minor|Feature|Patch|LatestMajor|LatestMinor|LatestFeature|LatestPatch|Disable|Default|Omit] -v Apply assembly version (defaulted: 1.0.0.0) -f Target framework moniker (defaulted: net6.0) -w Target Windows architecture [AnyCPU|Preferred32Bit|X86|X64|IA64|ARM|ARMv7|ARM64] @@ -77,7 +79,7 @@ usage: chibias [options] [ ...] ``` * chibiasは、コマンドラインで指摘された複数のソースコードをアセンブルして、1つの.NETアセンブリにまとめます。 -* 参照アセンブリパスは、`ld` のライブラリルックアップと同じように最後から順に評価されます。 +* 参照アセンブリパス `-l` は、`ld` のライブラリルックアップと同じように最後から順に評価されます。 この機能は、重複するシンボル(関数/グローバル変数)にも適用されます。 * ターゲットフレームワークのデフォルト(上記の例では`net6.0`)は、chibiasの動作環境に依存します。 * ターゲットフレームワークの指定は、コアライブラリのバリエーションを仮定するだけで、 @@ -104,7 +106,7 @@ chibiasを使って "Hello world" を実行してみましょう。 出来たら、chibiasを呼び出します: ```bash -$ chibias -f net45 -r /mnt/c/Windows/Microsoft.NET/Framework64/v4.0.30319/mscorlib.dll -o hello.exe hello.s +$ chibias -f net45 -L/mnt/c/Windows/Microsoft.NET/Framework64/v4.0.30319 -lmscorlib -o hello.exe hello.s ``` 実行します: @@ -144,7 +146,7 @@ $ echo $? ターゲットフレームワークを指定して、かつ参照アセンブリに`System.Private.CoreLib.dll`が含まれるようにします: ```bash -$ chibias -f net6.0 -r ~/.dotnet/shared/Microsoft.NETCore.App/6.0.13/System.Private.CoreLib.dll -o hello.exe hello.s +$ chibias -f net6.0 -L~/.dotnet/shared/Microsoft.NETCore.App/6.0.13 -lSystem.Private.CoreLib -o hello.exe hello.s ``` ターゲットフレームワークと、対応するコアライブラリのバージョンは一致する必要があります。 @@ -480,7 +482,7 @@ $ chibias -c test.s ``` ```bash -$ chibias -r test.dll main.s +$ chibias -ltest main.s ``` 関数(.NET CILメソッド)は、`C.text`という名前のクラス内に配置されます。 @@ -538,7 +540,7 @@ CABIが適用されるのは、外部アセンブリから参照可能な場合 シグネチャを指定せず、オーバーロードメソッドが複数存在する場合は、誤ったメソッドを選択する可能性があります。 通常、戻り値の型は検証されませんが、 `op_Implicit` 及び `op_Explicit` メソッドの場合のみ、戻り値の型も一致する事が確認されます。 -.NETメソッドを参照するために、コマンドラインオプション `-r` で、メソッド定義を含むアセンブリを指定する必要があります。これは、最も標準的な `mscorlib.dll` や `System.Runtime.dll` にも当てはまります。 +.NETメソッドを参照するために、コマンドラインオプション `-l` で、メソッド定義を含むアセンブリを指定する必要があります。これは、最も標準的な `mscorlib.dll` や `System.Runtime.dll` にも当てはまります。 補足: プロパティやインデクサを呼び出す必要がある場合は、それらを実装するメソッドのシグネチャを特定しておく必要があります。例えば: diff --git a/README.md b/README.md index 0b036f1..fa3358c 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Then: ```bash $ chibias -chibias [0.26.0,net6.0] [...] +chibias [0.41.0,net6.0] [...] This is the CIL assembler, part of chibicc-cil project. https://github.com/kekyo/chibias-cil Copyright (c) Kouji Matsui @@ -61,7 +61,9 @@ usage: chibias [options] [ ...] -c, --dll Produce dll assembly --exe Produce executable assembly (defaulted) --winexe Produce Windows executable assembly - -r Reference assembly path + -a AppHost template path + -L Reference assembly base path + -l Reference assembly name -g, -g2 Produce embedded debug symbol (defaulted) -g1 Produce portable debug symbol file -gm Produce mono debug symbol file @@ -69,7 +71,7 @@ usage: chibias [options] [ ...] -g0 Omit debug symbol file -O, -O1 Apply optimization -O0 Disable optimization (defaulted) - -s Suppress runtime configuration file + -p CoreCLR rollforward configuration [Major|Minor|Feature|Patch|LatestMajor|LatestMinor|LatestFeature|LatestPatch|Disable|Default|Omit] -v Apply assembly version (defaulted: 1.0.0.0) -f Target framework moniker (defaulted: net6.0) -w Target Windows architecture [AnyCPU|Preferred32Bit|X86|X64|IA64|ARM|ARMv7|ARM64] @@ -78,7 +80,7 @@ usage: chibias [options] [ ...] ``` * chibias will combine multiple source code in command line pointed into one assembly. -* Reference assembly paths evaluates last-to-first order, same as `ld` looking up. +* Reference assembly paths `-l` evaluates last-to-first order, same as `ld` looking up. This feature applies to duplicated symbols (function/global variables). * The default target framework moniker (`net6.0` in the above example) depends on the operating environment of chibias. * Specifying a target framework moniker only assumes a variation of the core library. @@ -105,7 +107,7 @@ You should create a new source code file `hello.s` with the contents only need 4 Then invoke chibias with: ```bash -$ chibias -f net45 -r /mnt/c/Windows/Microsoft.NET/Framework64/v4.0.30319/mscorlib.dll -o hello.exe hello.s +$ chibias -f net45 -L/mnt/c/Windows/Microsoft.NET/Framework64/v4.0.30319 -lmscorlib -o hello.exe hello.s ``` Run it: @@ -144,7 +146,7 @@ $ echo $? Specify the target framework moniker and make sure that the reference assembly `System.Private.CoreLib.dll`: ```bash -$ chibias -f net6.0 -r ~/.dotnet/shared/Microsoft.NETCore.App/6.0.13/System.Private.CoreLib.dll -o hello.exe hello.s +$ chibias -f net6.0 -L~/.dotnet/shared/Microsoft.NETCore.App/6.0.13 -lSystem.Private.CoreLib -o hello.exe hello.s ``` The version of the target framework moniker and the corresponding core library must match. @@ -487,7 +489,7 @@ Then: ``` ```bash -$ chibias -r test.dll main.s +$ chibias -ltest main.s ``` The functions (.NET CIL methods) are placed into single class named `C.text`. @@ -547,7 +549,7 @@ If no signature is specified and there are multiple overload methods, the wrong Generally, the return type is not verified, but the return type is also verified to match when using only for the `op_Implicit` and `op_Explicit` methods. -You have to give it containing assembly on command line option `-r`. +You have to give it containing assembly on command line option `-l`. This is true even for the most standard `mscorlib.dll` or `System.Runtime.dll`. Tip: If you need to call properties or indexers, diff --git a/chibias.core.Tests/AssemblerTests.MainFunctionWithReturnAndParameters.verified.txt b/chibias.core.Tests/AssemblerTests.MainFunctionWithReturnAndParameters.verified.txt index c31bc90..e9f8fef 100644 --- a/chibias.core.Tests/AssemblerTests.MainFunctionWithReturnAndParameters.verified.txt +++ b/chibias.core.Tests/AssemblerTests.MainFunctionWithReturnAndParameters.verified.txt @@ -25,64 +25,139 @@ // ================== GLOBAL METHODS ========================= -.method assembly static int32 _start(string[] args) cil managed +.method assembly static int32 _start() cil managed { .entrypoint - // Code size 81 (0x51) + // Code size 275 (0x113) .maxstack 3 - .locals (int8** V_0, - int32 V_1) - IL_0000: ldarg.0 - IL_0001: ldlen - IL_0002: conv.i4 - IL_0003: ldc.i4.1 - IL_0004: add - IL_0005: conv.u - IL_0006: sizeof int8* - IL_000c: mul.ovf.un - IL_000d: localloc - IL_000f: stloc.0 - IL_0010: ldloc.0 - IL_0011: call class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::GetEntryAssembly() - IL_0016: callvirt instance string [mscorlib]System.Reflection.Assembly::get_Location() - IL_001b: call native int [mscorlib]System.Runtime.InteropServices.Marshal::StringToCoTaskMemAnsi(string) - IL_0020: stind.i - IL_0021: ldc.i4.0 - IL_0022: stloc.1 - IL_0023: br.s IL_003f - - IL_0025: ldloc.0 - IL_0026: ldloc.1 - IL_0027: ldc.i4.1 - IL_0028: add - IL_0029: conv.i - IL_002a: sizeof int8* - IL_0030: mul - IL_0031: add - IL_0032: ldarg.0 - IL_0033: ldloc.1 - IL_0034: ldelem.ref - IL_0035: call native int [mscorlib]System.Runtime.InteropServices.Marshal::StringToCoTaskMemAnsi(string) - IL_003a: stind.i - IL_003b: ldloc.1 - IL_003c: ldc.i4.1 - IL_003d: add - IL_003e: stloc.1 - IL_003f: ldloc.1 - IL_0040: ldarg.0 - IL_0041: ldlen - IL_0042: conv.i4 - IL_0043: blt.s IL_0025 - - IL_0045: ldarg.0 - IL_0046: ldlen - IL_0047: conv.i4 - IL_0048: ldc.i4.1 - IL_0049: add - IL_004a: ldloc.0 - IL_004b: call int32 C.text::main(int32, + .locals (string[] V_0, + string V_1, + int8** V_2, + bool V_3, + string V_4, + bool V_5, + int32 V_6, + uint8[] V_7, + uint8[] V_8, + valuetype [mscorlib]System.Runtime.InteropServices.GCHandle V_9, + bool V_10) + IL_0000: call string[] [mscorlib]System.Environment::GetCommandLineArgs() + IL_0005: stloc V_0 + IL_0009: ldloc V_0 + IL_000d: ldc.i4.0 + IL_000e: ldelem.ref + IL_000f: stloc V_1 + IL_0013: ldloc V_1 + IL_0017: ldstr ".dll" + IL_001c: callvirt instance bool [mscorlib]System.String::EndsWith(string) + IL_0021: stloc.3 + IL_0022: ldloc.3 + IL_0023: brfalse.s IL_0084 + + IL_0025: call class [mscorlib]System.OperatingSystem [mscorlib]System.Environment::get_OSVersion() + IL_002a: callvirt instance valuetype [mscorlib]System.PlatformID [mscorlib]System.OperatingSystem::get_Platform() + IL_002f: ldc.i4.2 + IL_0030: beq.s IL_0039 + + IL_0032: ldstr "" + IL_0037: br.s IL_003e + + IL_0039: ldstr ".exe" + IL_003e: stloc.s V_4 + IL_0040: ldloc V_1 + IL_0044: call string [mscorlib]System.IO.Path::GetDirectoryName(string) + IL_0049: dup + IL_004a: brtrue.s IL_0052 + + IL_004c: pop + IL_004d: ldstr "" + IL_0052: ldloc V_1 + IL_0056: call string [mscorlib]System.IO.Path::GetFileNameWithoutExtension(string) + IL_005b: ldloc.s V_4 + IL_005d: call string [mscorlib]System.String::Concat(string, + string) + IL_0062: call string [mscorlib]System.IO.Path::Combine(string, + string) + IL_0067: stloc V_1 + IL_006b: ldloc V_1 + IL_006f: call bool [mscorlib]System.IO.File::Exists(string) + IL_0074: stloc.s V_5 + IL_0076: ldloc.s V_5 + IL_0078: brfalse.s IL_0084 + + IL_007a: ldloc V_0 + IL_007e: ldc.i4.0 + IL_007f: ldloc V_1 + IL_0083: stelem.ref + IL_0084: ldloc V_0 + IL_0088: ldlen + IL_0089: conv.i4 + IL_008a: ldc.i4.1 + IL_008b: add + IL_008c: conv.u + IL_008d: sizeof int8* + IL_0093: mul.ovf.un + IL_0094: localloc + IL_0096: stloc V_2 + IL_009a: ldc.i4.0 + IL_009b: stloc.s V_6 + IL_009d: br.s IL_00f3 + + IL_009f: call class [mscorlib]System.Text.Encoding [mscorlib]System.Text.Encoding::get_UTF8() + IL_00a4: ldloc V_0 + IL_00a8: ldloc.s V_6 + IL_00aa: ldelem.ref + IL_00ab: callvirt instance uint8[] [mscorlib]System.Text.Encoding::GetBytes(string) + IL_00b0: stloc.s V_7 + IL_00b2: ldloc.s V_7 + IL_00b4: ldlen + IL_00b5: conv.i4 + IL_00b6: ldc.i4.1 + IL_00b7: add + IL_00b8: newarr [mscorlib]System.SByte + IL_00bd: stloc.s V_8 + IL_00bf: ldloc.s V_7 + IL_00c1: ldloc.s V_8 + IL_00c3: ldloc.s V_7 + IL_00c5: ldlen + IL_00c6: conv.i4 + IL_00c7: call void [mscorlib]System.Array::Copy(class [mscorlib]System.Array, + class [mscorlib]System.Array, + int32) + IL_00cc: ldloc.s V_8 + IL_00ce: ldc.i4.3 + IL_00cf: call valuetype [mscorlib]System.Runtime.InteropServices.GCHandle [mscorlib]System.Runtime.InteropServices.GCHandle::Alloc(object, + valuetype [mscorlib]System.Runtime.InteropServices.GCHandleType) + IL_00d4: stloc.s V_9 + IL_00d6: ldloc V_2 + IL_00da: ldloc.s V_6 + IL_00dc: conv.i + IL_00dd: sizeof int8* + IL_00e3: mul + IL_00e4: add + IL_00e5: ldloca.s V_9 + IL_00e7: call instance native int [mscorlib]System.Runtime.InteropServices.GCHandle::AddrOfPinnedObject() + IL_00ec: stind.i + IL_00ed: ldloc.s V_6 + IL_00ef: ldc.i4.1 + IL_00f0: add + IL_00f1: stloc.s V_6 + IL_00f3: ldloc.s V_6 + IL_00f5: ldloc V_0 + IL_00f9: ldlen + IL_00fa: conv.i4 + IL_00fb: clt + IL_00fd: stloc.s V_10 + IL_00ff: ldloc.s V_10 + IL_0101: brtrue.s IL_009f + + IL_0103: ldloc V_0 + IL_0107: ldlen + IL_0108: conv.i4 + IL_0109: ldloc V_2 + IL_010d: call int32 C.text::main(int32, int8**) - IL_0050: ret + IL_0112: ret } // end of global method _start diff --git a/chibias.core.Tests/AssemblerTests.MainFunctionWithoutReturnAndParameters.verified.txt b/chibias.core.Tests/AssemblerTests.MainFunctionWithoutReturnAndParameters.verified.txt index c717a43..5a39e6a 100644 --- a/chibias.core.Tests/AssemblerTests.MainFunctionWithoutReturnAndParameters.verified.txt +++ b/chibias.core.Tests/AssemblerTests.MainFunctionWithoutReturnAndParameters.verified.txt @@ -25,64 +25,139 @@ // ================== GLOBAL METHODS ========================= -.method assembly static void _start(string[] args) cil managed +.method assembly static void _start() cil managed { .entrypoint - // Code size 81 (0x51) + // Code size 275 (0x113) .maxstack 3 - .locals (int8** V_0, - int32 V_1) - IL_0000: ldarg.0 - IL_0001: ldlen - IL_0002: conv.i4 - IL_0003: ldc.i4.1 - IL_0004: add - IL_0005: conv.u - IL_0006: sizeof int8* - IL_000c: mul.ovf.un - IL_000d: localloc - IL_000f: stloc.0 - IL_0010: ldloc.0 - IL_0011: call class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::GetEntryAssembly() - IL_0016: callvirt instance string [mscorlib]System.Reflection.Assembly::get_Location() - IL_001b: call native int [mscorlib]System.Runtime.InteropServices.Marshal::StringToCoTaskMemAnsi(string) - IL_0020: stind.i - IL_0021: ldc.i4.0 - IL_0022: stloc.1 - IL_0023: br.s IL_003f - - IL_0025: ldloc.0 - IL_0026: ldloc.1 - IL_0027: ldc.i4.1 - IL_0028: add - IL_0029: conv.i - IL_002a: sizeof int8* - IL_0030: mul - IL_0031: add - IL_0032: ldarg.0 - IL_0033: ldloc.1 - IL_0034: ldelem.ref - IL_0035: call native int [mscorlib]System.Runtime.InteropServices.Marshal::StringToCoTaskMemAnsi(string) - IL_003a: stind.i - IL_003b: ldloc.1 - IL_003c: ldc.i4.1 - IL_003d: add - IL_003e: stloc.1 - IL_003f: ldloc.1 - IL_0040: ldarg.0 - IL_0041: ldlen - IL_0042: conv.i4 - IL_0043: blt.s IL_0025 - - IL_0045: ldarg.0 - IL_0046: ldlen - IL_0047: conv.i4 - IL_0048: ldc.i4.1 - IL_0049: add - IL_004a: ldloc.0 - IL_004b: call void C.text::main(int32, + .locals (string[] V_0, + string V_1, + int8** V_2, + bool V_3, + string V_4, + bool V_5, + int32 V_6, + uint8[] V_7, + uint8[] V_8, + valuetype [mscorlib]System.Runtime.InteropServices.GCHandle V_9, + bool V_10) + IL_0000: call string[] [mscorlib]System.Environment::GetCommandLineArgs() + IL_0005: stloc V_0 + IL_0009: ldloc V_0 + IL_000d: ldc.i4.0 + IL_000e: ldelem.ref + IL_000f: stloc V_1 + IL_0013: ldloc V_1 + IL_0017: ldstr ".dll" + IL_001c: callvirt instance bool [mscorlib]System.String::EndsWith(string) + IL_0021: stloc.3 + IL_0022: ldloc.3 + IL_0023: brfalse.s IL_0084 + + IL_0025: call class [mscorlib]System.OperatingSystem [mscorlib]System.Environment::get_OSVersion() + IL_002a: callvirt instance valuetype [mscorlib]System.PlatformID [mscorlib]System.OperatingSystem::get_Platform() + IL_002f: ldc.i4.2 + IL_0030: beq.s IL_0039 + + IL_0032: ldstr "" + IL_0037: br.s IL_003e + + IL_0039: ldstr ".exe" + IL_003e: stloc.s V_4 + IL_0040: ldloc V_1 + IL_0044: call string [mscorlib]System.IO.Path::GetDirectoryName(string) + IL_0049: dup + IL_004a: brtrue.s IL_0052 + + IL_004c: pop + IL_004d: ldstr "" + IL_0052: ldloc V_1 + IL_0056: call string [mscorlib]System.IO.Path::GetFileNameWithoutExtension(string) + IL_005b: ldloc.s V_4 + IL_005d: call string [mscorlib]System.String::Concat(string, + string) + IL_0062: call string [mscorlib]System.IO.Path::Combine(string, + string) + IL_0067: stloc V_1 + IL_006b: ldloc V_1 + IL_006f: call bool [mscorlib]System.IO.File::Exists(string) + IL_0074: stloc.s V_5 + IL_0076: ldloc.s V_5 + IL_0078: brfalse.s IL_0084 + + IL_007a: ldloc V_0 + IL_007e: ldc.i4.0 + IL_007f: ldloc V_1 + IL_0083: stelem.ref + IL_0084: ldloc V_0 + IL_0088: ldlen + IL_0089: conv.i4 + IL_008a: ldc.i4.1 + IL_008b: add + IL_008c: conv.u + IL_008d: sizeof int8* + IL_0093: mul.ovf.un + IL_0094: localloc + IL_0096: stloc V_2 + IL_009a: ldc.i4.0 + IL_009b: stloc.s V_6 + IL_009d: br.s IL_00f3 + + IL_009f: call class [mscorlib]System.Text.Encoding [mscorlib]System.Text.Encoding::get_UTF8() + IL_00a4: ldloc V_0 + IL_00a8: ldloc.s V_6 + IL_00aa: ldelem.ref + IL_00ab: callvirt instance uint8[] [mscorlib]System.Text.Encoding::GetBytes(string) + IL_00b0: stloc.s V_7 + IL_00b2: ldloc.s V_7 + IL_00b4: ldlen + IL_00b5: conv.i4 + IL_00b6: ldc.i4.1 + IL_00b7: add + IL_00b8: newarr [mscorlib]System.SByte + IL_00bd: stloc.s V_8 + IL_00bf: ldloc.s V_7 + IL_00c1: ldloc.s V_8 + IL_00c3: ldloc.s V_7 + IL_00c5: ldlen + IL_00c6: conv.i4 + IL_00c7: call void [mscorlib]System.Array::Copy(class [mscorlib]System.Array, + class [mscorlib]System.Array, + int32) + IL_00cc: ldloc.s V_8 + IL_00ce: ldc.i4.3 + IL_00cf: call valuetype [mscorlib]System.Runtime.InteropServices.GCHandle [mscorlib]System.Runtime.InteropServices.GCHandle::Alloc(object, + valuetype [mscorlib]System.Runtime.InteropServices.GCHandleType) + IL_00d4: stloc.s V_9 + IL_00d6: ldloc V_2 + IL_00da: ldloc.s V_6 + IL_00dc: conv.i + IL_00dd: sizeof int8* + IL_00e3: mul + IL_00e4: add + IL_00e5: ldloca.s V_9 + IL_00e7: call instance native int [mscorlib]System.Runtime.InteropServices.GCHandle::AddrOfPinnedObject() + IL_00ec: stind.i + IL_00ed: ldloc.s V_6 + IL_00ef: ldc.i4.1 + IL_00f0: add + IL_00f1: stloc.s V_6 + IL_00f3: ldloc.s V_6 + IL_00f5: ldloc V_0 + IL_00f9: ldlen + IL_00fa: conv.i4 + IL_00fb: clt + IL_00fd: stloc.s V_10 + IL_00ff: ldloc.s V_10 + IL_0101: brtrue.s IL_009f + + IL_0103: ldloc V_0 + IL_0107: ldlen + IL_0108: conv.i4 + IL_0109: ldloc V_2 + IL_010d: call void C.text::main(int32, int8**) - IL_0050: ret + IL_0112: ret } // end of global method _start diff --git a/chibias.core.Tests/Runner.cs b/chibias.core.Tests/Runner.cs index 94bc597..7e706b9 100644 --- a/chibias.core.Tests/Runner.cs +++ b/chibias.core.Tests/Runner.cs @@ -62,16 +62,16 @@ private string Run( Select(Utilities.GetDirectoryPath). Distinct(). ToArray(); - var referenceAssemblyPaths = new[] + var referenceAssemblyNames = new[] { coreLibPath, tmp2Path, }. Concat(additionalReferencePaths ?? Array.Empty()). + Select(Path.GetFileNameWithoutExtension). + Distinct(). ToArray(); - var assember = new Assembler( - logger, - referenceAssemblyBasePaths); + var assember = new Assembler(logger); var outputAssemblyPath = Path.Combine(basePath, "output.dll"); @@ -81,7 +81,8 @@ private string Run( outputAssemblyPath, new() { - ReferenceAssemblyPaths = referenceAssemblyPaths, + ReferenceAssemblyBasePaths = referenceAssemblyBasePaths, + ReferenceAssemblyNames = referenceAssemblyNames!, AssemblyType = assemblyType, TargetFramework = tf, DebugSymbolType = DebugSymbolTypes.Embedded, diff --git a/chibias.core/Assembler.cs b/chibias.core/Assembler.cs index 53139ef..8675937 100644 --- a/chibias.core/Assembler.cs +++ b/chibias.core/Assembler.cs @@ -49,47 +49,33 @@ public sealed class Assembler Encoding.UTF8.GetBytes("c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2"); private readonly ILogger logger; - private readonly DefaultAssemblyResolver assemblyResolver; - private readonly ReaderParameters readerParameters; - public Assembler( - ILogger logger, - params string[] referenceAssemblyBasePaths) - { + public Assembler(ILogger logger) => this.logger = logger; - this.assemblyResolver = new DefaultAssemblyResolver(); - this.readerParameters = new(ReadingMode.Immediate) - { - InMemory = true, - ReadSymbols = false, - ReadWrite = false, - ThrowIfSymbolsAreNotMatching = false, - AssemblyResolver = this.assemblyResolver, - }; - - foreach (var basePath in referenceAssemblyBasePaths) - { - this.assemblyResolver.AddSearchDirectory(basePath); - } - } private TypeDefinitionCache LoadPublicTypesFrom( - string[] referenceAssemblyPaths) + string[] referenceAssemblyBasePaths, + string[] referenceAssemblyNames, + ReaderParameters readerParameters) { - var assemblies = referenceAssemblyPaths. + var assemblies = referenceAssemblyNames. Distinct(). - Collect(path => + Collect(name => { try { - if (!File.Exists(path)) + if (referenceAssemblyBasePaths. + SelectMany(basePath => new[] { $"{name}.dll", $"lib{name}.dll" }. + Select(n => Path.Combine(basePath, n))). + Where(File.Exists). + FirstOrDefault() is not { } path) { this.logger.Warning( - $"Unable to find reference assembly: {path}"); + $"Unable to find reference assembly: {name}"); return null; } - var assembly = AssemblyDefinition.ReadAssembly(path, this.readerParameters); + var assembly = AssemblyDefinition.ReadAssembly(path, readerParameters); this.logger.Information( $"Read reference assembly: {path}"); return assembly; @@ -97,7 +83,7 @@ private TypeDefinitionCache LoadPublicTypesFrom( catch (Exception ex) { this.logger.Warning( - $"Unable to read reference assembly: {path}, {ex.GetType().FullName}: {ex.Message}"); + $"Unable to read reference assembly: {name}, {ex.GetType().FullName}: {ex.Message}"); return null; } }) @@ -339,6 +325,21 @@ private bool Run( AssemblerOptions options, Func runner) { + using var assemblyResolver = new DefaultAssemblyResolver(); + foreach (var basePath in options.ReferenceAssemblyBasePaths) + { + assemblyResolver.AddSearchDirectory(basePath); + } + + var readerParameters = new ReaderParameters(ReadingMode.Immediate) + { + InMemory = true, + ReadSymbols = false, + ReadWrite = false, + ThrowIfSymbolsAreNotMatching = false, + AssemblyResolver = assemblyResolver, + }; + var produceExecutable = options.AssemblyType != AssemblyTypes.Dll; @@ -373,7 +374,7 @@ options.AppHostTemplatePath is { } appHostTemplatePath && _ => ModuleKind.Console }, Runtime = options.TargetFramework.Runtime, - AssemblyResolver = this.assemblyResolver, + AssemblyResolver = assemblyResolver, Architecture = options.TargetWindowsArchitecture switch { TargetWindowsArchitectures.X64 => TargetArchitecture.AMD64, @@ -397,9 +398,9 @@ options.AppHostTemplatePath is { } appHostTemplatePath && }; // https://github.com/jbevain/cecil/issues/646 - var coreLibraryReference = this.assemblyResolver.Resolve( + var coreLibraryReference = assemblyResolver.Resolve( options.TargetFramework.CoreLibraryName, - this.readerParameters); + readerParameters); module.AssemblyReferences.Add(coreLibraryReference.Name); // The type system will be bring with explicitly assigned core library. @@ -415,7 +416,9 @@ options.AppHostTemplatePath is { } appHostTemplatePath && ////////////////////////////////////////////////////////////// var referenceTypes = this.LoadPublicTypesFrom( - options.ReferenceAssemblyPaths); + options.ReferenceAssemblyBasePaths, + options.ReferenceAssemblyNames, + readerParameters); var cabiSpecificSymbols = this.AggregateCAbiSpecificSymbols( referenceTypes); diff --git a/chibias.core/AssemblerExtension.cs b/chibias.core/AssemblerExtension.cs index 4d6c8ad..e924746 100644 --- a/chibias.core/AssemblerExtension.cs +++ b/chibias.core/AssemblerExtension.cs @@ -16,7 +16,8 @@ public static class AssemblerExtension public static bool Assemble( this Assembler assembler, string outputAssemblyPath, - string[] referenceAssemblyPaths, + string[] referenceAssemblyBasePaths, + string[] referenceAssemblyNames, AssemblyTypes assemblyType, DebugSymbolTypes debugSymbolType, AssembleOptions options, @@ -27,7 +28,8 @@ public static bool Assemble( outputAssemblyPath, new() { - ReferenceAssemblyPaths = referenceAssemblyPaths, + ReferenceAssemblyBasePaths = referenceAssemblyBasePaths, + ReferenceAssemblyNames = referenceAssemblyNames, AssemblyType = assemblyType, DebugSymbolType = debugSymbolType, Options = options, diff --git a/chibias.core/AssemblerOptions.cs b/chibias.core/AssemblerOptions.cs index a9cf2be..4d433d3 100644 --- a/chibias.core/AssemblerOptions.cs +++ b/chibias.core/AssemblerOptions.cs @@ -66,7 +66,9 @@ public enum RuntimeConfigurationOptions public sealed class AssemblerOptions { - public string[] ReferenceAssemblyPaths = + public string[] ReferenceAssemblyBasePaths = + Utilities.Empty(); + public string[] ReferenceAssemblyNames = Utilities.Empty(); public AssemblyTypes AssemblyType = AssemblyTypes.Exe; diff --git a/chibias/Options.cs b/chibias/Options.cs index d1d39f1..d8b3999 100644 --- a/chibias/Options.cs +++ b/chibias/Options.cs @@ -33,7 +33,6 @@ internal sealed class Options }; public string OutputAssemblyPath = null!; - public readonly List ReferenceAssemblyBasePaths = new(); public readonly AssemblerOptions AssemblerOptions = new(); public LogLevels LogLevel = LogLevels.Warning; public bool ShowHelp = false; @@ -46,7 +45,8 @@ private Options() public static Options Parse(string[] args) { var options = new Options(); - var referenceAssemblyPaths = new List(); + var referenceAssemblyBasePaths = new List(); + var referenceAssemblyNames = new List(); options.AssemblerOptions.TargetFramework = TargetFramework.TryParse(ThisAssembly.AssemblyMetadata.TargetFrameworkMoniker, out var tf) ? @@ -77,19 +77,33 @@ public static Options Parse(string[] args) continue; } break; - case 'r': + case 'L': if (arg.Length >= 3) { - var referenceAssemblyPath = + var referenceAssemblyBasePath = Path.GetFullPath(arg.Substring(2)); - referenceAssemblyPaths.Add(referenceAssemblyPath); + referenceAssemblyBasePaths.Add(referenceAssemblyBasePath); continue; } else if (args.Length >= index) { - var referenceAssemblyPath = + var referenceAssemblyBasePath = Path.GetFullPath(args[++index]); - referenceAssemblyPaths.Add(referenceAssemblyPath); + referenceAssemblyBasePaths.Add(referenceAssemblyBasePath); + continue; + } + break; + case 'l': + if (arg.Length >= 3) + { + var referenceAssemblyName = arg.Substring(2); + referenceAssemblyNames.Add(referenceAssemblyName); + continue; + } + else if (args.Length >= index) + { + var referenceAssemblyName = args[++index]; + referenceAssemblyNames.Add(referenceAssemblyName); continue; } break; @@ -276,13 +290,12 @@ public static Options Parse(string[] args) } } - options.AssemblerOptions.ReferenceAssemblyPaths = - referenceAssemblyPaths.ToArray(); - - options.ReferenceAssemblyBasePaths.AddRange( - options.AssemblerOptions.ReferenceAssemblyPaths. - Select(Utilities.GetDirectoryPath). - Distinct()); + options.AssemblerOptions.ReferenceAssemblyBasePaths = referenceAssemblyBasePaths. + Distinct(). + ToArray(); + options.AssemblerOptions.ReferenceAssemblyNames = referenceAssemblyNames. + Distinct(). + ToArray(); return options; } @@ -296,14 +309,14 @@ public void Write(ILogger logger) logger.Information($"OutputAssemblyPath={this.OutputAssemblyPath}"); - foreach (var path in this.AssemblerOptions.ReferenceAssemblyPaths) + foreach (var path in this.AssemblerOptions.ReferenceAssemblyBasePaths) { - logger.Information($"ReferenceAssemblyPath={path}"); + logger.Information($"ReferenceAssemblyBasePath={path}"); } - foreach (var path in this.ReferenceAssemblyBasePaths) + foreach (var name in this.AssemblerOptions.ReferenceAssemblyNames) { - logger.Information($"ReferenceAssemblyBasePath={path}"); + logger.Information($"ReferenceAssemblyName={name}"); } logger.Information($"AssemblyType={this.AssemblerOptions.AssemblyType}"); @@ -330,7 +343,8 @@ public static void WriteUsage(TextWriter tw) tw.WriteLine(" --exe Produce executable assembly (defaulted)"); tw.WriteLine(" --winexe Produce Windows executable assembly"); tw.WriteLine(" -a AppHost template path"); - tw.WriteLine(" -r Reference assembly path"); + tw.WriteLine(" -L Reference assembly base path"); + tw.WriteLine(" -l Reference assembly name"); tw.WriteLine(" -g, -g2 Produce embedded debug symbol (defaulted)"); tw.WriteLine(" -g1 Produce portable debug symbol file"); tw.WriteLine(" -gm Produce mono debug symbol file"); diff --git a/chibias/Program.cs b/chibias/Program.cs index 8e73a62..a822847 100644 --- a/chibias/Program.cs +++ b/chibias/Program.cs @@ -36,9 +36,7 @@ public static int Main(string[] args) options.Write(logger); - var assembler = new Assembler( - logger, - options.ReferenceAssemblyBasePaths.ToArray()); + var assembler = new Assembler(logger); if (assembler.Assemble( options.OutputAssemblyPath, diff --git a/chibias/Properties/launchSettings.json b/chibias/Properties/launchSettings.json index 3478c99..d5f6552 100644 --- a/chibias/Properties/launchSettings.json +++ b/chibias/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "chibias": { "commandName": "Project", - "commandLineArgs": "--log trace -f net6.0 -a /home/kouji/.dotnet/sdk/6.0.418/AppHostTemplate/apphost -r /home/kouji/.dotnet/shared/Microsoft.NETCore.App/6.0.26/System.Private.CoreLib.dll -r stage2/libc-bootstrap.dll -o stage2/chibicc stage2/./codegen.o stage2/./main.o stage2/./parse.o stage2/./strings.o stage2/./tokenize.o stage2/./type.o stage2/./utils.o", + "commandLineArgs": "--log trace -f net6.0 -a /home/kouji/.dotnet/sdk/6.0.418/AppHostTemplate/apphost -L/home/kouji/.dotnet/shared/Microsoft.NETCore.App/6.0.26 -lSystem.Private.CoreLib -L. -lc-bootstrap -o test/alignof test/alignof.o test/common.o", "workingDirectory": "/home/kouji/Projects/chibicc-cil" } }