Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
kekyo committed May 9, 2024
2 parents aeab549 + eeab223 commit 40da33a
Show file tree
Hide file tree
Showing 36 changed files with 366 additions and 154 deletions.
14 changes: 7 additions & 7 deletions README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,15 @@ $ dotnet tool install -g chibild-cli
使用可能になったかどうかは、以下のように確認できます:

```bash
$ cil-chibild
$ cil-ecma-chibild

cil-chibild [0.60.0,net6.0] [...]
cil-ecma-chibild [0.63.0,net6.0] [...]
This is the CIL object linker, part of chibicc-cil project.
https://github.com/kekyo/chibicc-cil-toolchain
Copyright (c) Kouji Matsui
License under MIT

usage: cil-chibild [options] <input path> [<input path> ...]
usage: cil-ecma-chibild [options] <input path> [<input path> ...]
-o <path> Output assembly path
-shared, -mdll Produce dll assembly
-mexe Produce executable assembly (defaulted)
Expand Down Expand Up @@ -149,7 +149,7 @@ chibildを使って "Hello world" を実行してみましょう。
出来たら、chibildを呼び出します:

```bash
$ cil-chibild -mnet45 -L/mnt/c/Windows/Microsoft.NET/Framework64/v4.0.30319 -lmscorlib -o hello.exe hello.s
$ cil-ecma-chibild -mnet45 -L/mnt/c/Windows/Microsoft.NET/Framework64/v4.0.30319 -lmscorlib -o hello.exe hello.s
```

実行します:
Expand All @@ -176,7 +176,7 @@ Linuxや他のOSでも、必要な参照を追加することで同じように
```

```bash
$ cil-chibild -mnet45 -o adder.exe adder.s
$ cil-ecma-chibild -mnet45 -o adder.exe adder.s
$ ./adder.exe
$ echo $?
3
Expand All @@ -190,7 +190,7 @@ $ echo $?
ターゲットフレームワークを指定して、かつ参照アセンブリに`System.Private.CoreLib.dll`が含まれるようにします:

```bash
$ cil-chibild -mnet6.0 -L$HOME/.dotnet/shared/Microsoft.NETCore.App/6.0.13 -lSystem.Private.CoreLib \
$ cil-ecma-chibild -mnet6.0 -L$HOME/.dotnet/shared/Microsoft.NETCore.App/6.0.13 -lSystem.Private.CoreLib \
-o hello.exe hello.s
```

Expand Down Expand Up @@ -1010,7 +1010,7 @@ public static class text
以下のコマンドを使用して `injected.dll` を生成します:

```bash
$ cil-chibild -mnet6.0 -L$HOME/.dotnet/shared/Microsoft.NETCore.App/6.0.13 -lSystem.Private.CoreLib \
$ cil-ecma-chibild -mnet6.0 -L$HOME/.dotnet/shared/Microsoft.NETCore.App/6.0.13 -lSystem.Private.CoreLib \
-i managed.dll -c -o injected.dll add_c.s
```

Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,15 @@ $ dotnet tool install -g chibild-cli
Then:

```bash
$ cil-chibild
$ cil-ecma-chibild

cil-chibild [0.60.0,net6.0] [...]
cil-ecma-chibild [0.63.0,net6.0] [...]
This is the CIL object linker, part of chibicc-cil project.
https://github.com/kekyo/chibicc-cil-toolchain
Copyright (c) Kouji Matsui
License under MIT

usage: cil-chibild [options] <input path> [<input path> ...]
usage: cil-ecma-chibild [options] <input path> [<input path> ...]
-o <path> Output assembly path
-shared, -mdll Produce dll assembly
-mexe Produce executable assembly (defaulted)
Expand Down Expand Up @@ -152,7 +152,7 @@ You should create a new source code file `hello.s` with the contents only need 4
Then invoke chibild with:

```bash
$ cil-chibild -mnet45 -L/mnt/c/Windows/Microsoft.NET/Framework64/v4.0.30319 -lmscorlib -o hello.exe hello.s
$ cil-ecma-chibild -mnet45 -L/mnt/c/Windows/Microsoft.NET/Framework64/v4.0.30319 -lmscorlib -o hello.exe hello.s
```

Run it:
Expand All @@ -177,7 +177,7 @@ Also, if you assemble code that uses only built-in types (see below), you do not
```

```bash
$ cil-chibild -mnet45 -o adder.exe adder.s
$ cil-ecma-chibild -mnet45 -o adder.exe adder.s
$ ./adder.exe
$ echo $?
3
Expand All @@ -191,7 +191,7 @@ $ echo $?
Specify the target framework moniker and make sure that the reference assembly `System.Private.CoreLib.dll`:

```bash
$ cil-chibild -mnet6.0 -L$HOME/.dotnet/shared/Microsoft.NETCore.App/6.0.13 -lSystem.Private.CoreLib \
$ cil-ecma-chibild -mnet6.0 -L$HOME/.dotnet/shared/Microsoft.NETCore.App/6.0.13 -lSystem.Private.CoreLib \
-o hello.exe hello.s
```

Expand Down Expand Up @@ -1036,7 +1036,7 @@ Using injection mode, you can "inject" the following CIL code directly into `man
To `injected.dll` by the command:

```bash
$ cil-chibild -mnet6.0 -L$HOME/.dotnet/shared/Microsoft.NETCore.App/6.0.13 -lSystem.Private.CoreLib \
$ cil-ecma-chibild -mnet6.0 -L$HOME/.dotnet/shared/Microsoft.NETCore.App/6.0.13 -lSystem.Private.CoreLib \
-i managed.dll -c -o injected.dll add_c.s
```

Expand Down
23 changes: 20 additions & 3 deletions chibiar/chibiar.core.Tests/ArchiverTestRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using chibicc.toolchain.Logging;
using DiffEngine;

namespace chibiar;
Expand All @@ -32,15 +34,30 @@ static ArchiverTestRunner()
private static readonly string id =
$"{DateTime.Now:yyyyMMdd_HHmmss_fff}_{new Random().Next()}";

public static Task RunAsync(
Func<string, Task> tester,
public static async Task RunAsync(
Func<string, TextWriterLogger, Task> tester,
[CallerMemberName] string memberName = null!)
{
var basePath = Path.GetFullPath(
Path.Combine("tests", id, memberName));

Directory.CreateDirectory(basePath);

return tester(basePath);
var logPath = Path.Combine(basePath, "log.txt");
using var logfs = new FileStream(
logPath, FileMode.Create, FileAccess.ReadWrite, FileShare.None);
var logtw = new StreamWriter(
logfs, Encoding.UTF8);
var logger = new TextWriterLogger(
LogLevels.Debug, logtw);

try
{
await tester(basePath, logger);
}
finally
{
await logtw.FlushAsync();
}
}
}
12 changes: 7 additions & 5 deletions chibiar/chibiar.core.Tests/ArchiverTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
using System.Text;
using System.Threading.Tasks;
using chibicc.toolchain.Archiving;

using chibicc.toolchain.Logging;
using static VerifyNUnit.Verifier;
using static chibiar.ArchiverTestRunner;

Expand All @@ -38,11 +38,13 @@ private static async Task VerifySymbolTableAsync(ZipArchive zip)
[Test]
public Task ArchiveOne()
{
return RunAsync(async basePath =>
return RunAsync(async (basePath, logger) =>
{
logger.Information($"Test runner BasePath={basePath}");
var archivePath = Path.Combine(basePath, "output.a");
var archiver = new Archiver();
var archiver = new Archiver(logger);
var actual = archiver.Add(
archivePath,
SymbolTableModes.Auto,
Expand All @@ -67,11 +69,11 @@ public Task ArchiveOne()
[Test]
public Task ArchiveTwo()
{
return RunAsync(async basePath =>
return RunAsync(async (basePath, logger) =>
{
var archivePath = Path.Combine(basePath, "output.a");
var archiver = new Archiver();
var archiver = new Archiver(logger);
var actual = archiver.Add(
archivePath,
SymbolTableModes.Auto,
Expand Down
Binary file modified chibiar/chibiar.core.Tests/artifacts/codegen.o
Binary file not shown.
Binary file modified chibiar/chibiar.core.Tests/artifacts/parse.o
Binary file not shown.
61 changes: 52 additions & 9 deletions chibiar/chibiar.core/Archiver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using chibiar.cli;
using chibicc.toolchain.Archiving;
using chibicc.toolchain.Internal;
using chibicc.toolchain.IO;
using chibicc.toolchain.Logging;

namespace chibiar;

Expand All @@ -33,7 +36,12 @@ public enum AddResults

public sealed class Archiver
{
private static SymbolList ReadSymbols(
private readonly ILogger logger;

public Archiver(ILogger logger) =>
this.logger = logger;

private SymbolList ReadSymbols(
string objectFilePath,
SymbolTableModes symbolTableMode)
{
Expand All @@ -42,7 +50,7 @@ private static SymbolList ReadSymbols(
if (symbolTableMode == SymbolTableModes.ForceUpdate ||
(symbolTableMode == SymbolTableModes.Auto && Path.GetExtension(objectFilePath) is ".o" or ".s"))
{
using var ofs = StreamUtilities.OpenStream(objectFilePath, false);
using var ofs = ObjectStreamUtilities.OpenObjectStream(objectFilePath, false);

var symbols = ArchiverUtilities.EnumerateSymbolsFromObjectFile(ofs).
ToArray();
Expand All @@ -51,11 +59,22 @@ private static SymbolList ReadSymbols(
}
else
{
return new SymbolList(objectName, new Symbol[0]);
return new SymbolList(objectName, CommonUtilities.Empty<Symbol>());
}
}

public AddResults Add(
private static bool IsSourceFile(string path) =>
Path.GetExtension(path) is not ".o";

private static Stream OpenObjectStreamToCompressed(string objectFilePath)
{
var ofs = StreamUtilities.OpenStream(objectFilePath, false);

return IsSourceFile(objectFilePath) ?
new GZipStream(ofs, CompressionLevel.Optimal) : ofs;
}

internal AddResults Add(
string archiveFilePath,
SymbolTableModes symbolTableMode,
string[] objectFilePaths,
Expand All @@ -79,12 +98,16 @@ public AddResults Add(
{
if (archive != null)
{
using var ofs = StreamUtilities.OpenStream(objectFilePath, false);
var fileName = Path.GetExtension(objectFilePath) == ".s" ?
using var ofs = OpenObjectStreamToCompressed(objectFilePath);
var fileName = IsSourceFile(objectFilePath) ?
(Path.GetFileNameWithoutExtension(objectFilePath) + ".o") :
Path.GetFileName(objectFilePath);
var entry = archive.CreateEntry(fileName, CompressionLevel.Optimal);
var entry = archive.CreateEntry(
fileName,
CompressionLevel.NoCompression); // ofs is already gzip compressed.
entry.LastWriteTime = File.GetLastWriteTime(objectFilePath);
using var afs = entry.Open();
Expand All @@ -105,7 +128,7 @@ public AddResults Add(
Concat(objectFilePaths.Select((objectFilePath, index) =>
new Action(() =>
{
var symbolList = ReadSymbols(objectFilePath, symbolTableMode);
var symbolList = this.ReadSymbols(objectFilePath, symbolTableMode);
symbolLists[index] = symbolList;
}))).
ToArray();
Expand All @@ -124,4 +147,24 @@ public AddResults Add(

return updated ? AddResults.Updated : AddResults.Created;
}

public void Archive(CliOptions options)
{
switch (options.Mode)
{
case ArchiveModes.Add:
if (this.Add(
options.ArchiveFilePath,
options.SymbolTableMode,
options.ObjectFilePaths.ToArray(),
options.IsDryRun) == AddResults.Created &&
!options.IsSilent)
{
this.logger.Information($"creating {Path.GetFileName(options.ArchiveFilePath)}");
}
break;
default:
throw new NotImplementedException();
}
}
}
12 changes: 12 additions & 0 deletions chibiar/chibiar.core/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/////////////////////////////////////////////////////////////////////////////////////
//
// chibicc-toolchain - The specialized backend toolchain for chibicc-cil
// Copyright (c) Kouji Matsui(@kozy_kekyo, @kekyo @mastodon.cloud)
//
// Licensed under MIT: https://opensource.org/licenses/MIT
//
/////////////////////////////////////////////////////////////////////////////////////

using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("chibiar.core.Tests")]
33 changes: 19 additions & 14 deletions chibiar/chibiar.core/cli/CliOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using chibicc.toolchain.Logging;

namespace chibiar.cli;

Expand All @@ -28,6 +29,7 @@ public sealed class CliOptions
public bool IsSilent = false;
public SymbolTableModes SymbolTableMode = SymbolTableModes.Auto;
public bool IsDryRun = false;
public LogLevels LogLevel = LogLevels.Warning;
public bool ShowHelp = false;
public readonly List<string> ObjectFilePaths = new();

Expand Down Expand Up @@ -79,6 +81,15 @@ public static CliOptions Parse(string[] args)
case '-':
switch (arg0.Substring(1).ToLowerInvariant())
{
case "log":
if (args.Length >= index &&
Enum.TryParse<LogLevels>(args[index + 1], true, out var logLevel))
{
index++;
options.LogLevel = logLevel;
continue;
}
break;
case "dryrun":
options.IsDryRun = true;
continue;
Expand Down Expand Up @@ -126,20 +137,14 @@ public static CliOptions Parse(string[] args)

public static void WriteUsage(TextWriter tw)
{
tw.WriteLine($"cil-chibiar [{ThisAssembly.AssemblyVersion},{ThisAssembly.AssemblyMetadata.TargetFrameworkMoniker}] [{ThisAssembly.AssemblyMetadata.CommitId}]");
tw.WriteLine("This is a CIL object archiver, part of chibicc-cil project.");
tw.WriteLine("https://github.com/kekyo/chibicc-cil-toolchain");
tw.WriteLine("Copyright (c) Kouji Matsui");
tw.WriteLine("License under MIT");
tw.WriteLine();
tw.WriteLine("usage: cil-chibiar [options] <archive path> [<obj path> ...]");
tw.WriteLine(" -r Add object files into the archive");
tw.WriteLine(" -c Add object files into the archive silently");
tw.WriteLine(" -s Add symbol table");
tw.WriteLine(" -d Delete object files from the archive");
tw.WriteLine(" -t List object files in the archive");
tw.WriteLine(" --dryrun Need to dryrun");
tw.WriteLine(" -h, --help Show this help");
tw.WriteLine(" -r Add object files into the archive");
tw.WriteLine(" -c Add object files into the archive silently");
tw.WriteLine(" -s Add symbol table");
tw.WriteLine(" -d Delete object files from the archive");
tw.WriteLine(" -t List object files in the archive");
tw.WriteLine(" --log <level> Log level [debug|trace|information|warning|error|silent] (defaulted: warning)");
tw.WriteLine(" --dryrun Need to dryrun");
tw.WriteLine(" -h, --help Show this help");
}
}

Expand Down
Loading

0 comments on commit 40da33a

Please sign in to comment.