# 機能設計書 52-ilasm

## 概要

本ドキュメントは、.NETランタイムにおけるilasm（ILアセンブラ）の機能設計を記述する。ilasmは、CIL（Common Intermediate Language）ソースコードをアセンブルし、.NETアセンブリ（DLLまたはEXE）を生成するコマンドラインツールである。

### 本機能の処理概要

ilasmは、テキスト形式のILソースファイル（.ilファイル）を読み込み、CLRメタデータとILバイトコードを含むPE（Portable Executable）ファイルを生成する機能である。

**業務上の目的・背景**：.NETランタイムの開発・テスト・デバッグにおいて、低レベルなILコードを直接記述・編集する必要がある場面が存在する。ilasmは、ildasmで逆アセンブルされたコードの再アセンブル、ランタイムテストコードの生成、IL構文の検証などに使用される。

**機能の利用シーン**：
- ランタイムテストの作成（特定のIL命令パターンの検証）
- ildasmで出力したILソースの修正と再アセンブル
- デバッグ情報（PDB）を含むアセンブリの生成
- リソース埋め込みアセンブリの作成

**主要な処理内容**：
1. ILソースコードの字句解析（Lexer）とパース（Parser）
2. 型・メソッド・フィールドなどのエンティティ登録
3. メタデータテーブルの構築（System.Reflection.Metadata使用）
4. ILバイトコードの生成
5. PEファイルの出力
6. デバッグ情報（Portable PDB）の生成（オプション）

**関連システム・外部連携**：
- ANTLR4パーサージェネレータを使用した構文解析
- System.Reflection.Metadata.Ecma335によるメタデータ生成
- System.Reflection.PortableExecutableによるPE出力

**権限による制御**：特別な権限制御は行わない。ファイルシステムへの書き込み権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | ilasmはCLIツールのため、直接的なUI関連はない |

## 機能種別

開発ツール / コンパイラ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| sourceFile | string | Yes | ILソースファイルパス | 存在するファイル |
| /output | string | No | 出力ファイルパス | 書き込み可能なパス |
| /dll | flag | No | DLLとして出力 | - |
| /exe | flag | No | EXEとして出力 | - |
| /debug | flag | No | デバッグ情報を生成 | - |
| /pdb | flag | No | Portable PDBを生成 | - |
| /resource | string | No | 埋め込みリソースファイル | 存在するファイル |
| /noautoinherit | flag | No | System.Objectからの自動継承を無効化 | - |

### 入力データソース

- ILソースファイル（.il）
- インクルードファイル（#include指令）
- リソースファイル

### ILソース文法（抜粋）

```
.assembly extern mscorlib {}
.assembly MyAssembly { .ver 1:0:0:0 }
.module MyModule.dll

.class public MyClass extends [mscorlib]System.Object
{
    .method public static void Main() cil managed
    {
        .entrypoint
        .maxstack 1
        ldstr "Hello, World!"
        call void [mscorlib]System.Console::WriteLine(string)
        ret
    }
}
```

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| assembly | PE file | 生成されたアセンブリ（.dllまたは.exe） |
| pdb | PDB file | デバッグ情報（オプション） |
| diagnostics | Diagnostic[] | 警告・エラーメッセージ |

### 出力先

- 指定された出力パス、またはソースファイルと同じディレクトリ
- 標準出力（診断メッセージ）

## 処理フロー

### 処理シーケンス

```
1. ソースファイル読み込み
   └─ SourceText生成

2. 字句解析
   └─ CILLexerによるトークン化
   └─ プリプロセッサ処理（#include等）

3. 構文解析
   └─ CILParserによる構文木生成
   └─ GrammarVisitorによる走査

4. エンティティ登録
   └─ EntityRegistryに型・メソッド・フィールドを登録
   └─ 前方参照の解決

5. メタデータ構築
   └─ MetadataBuilderでテーブル構築
   └─ 署名のエンコード

6. ILバイトコード生成
   └─ InstructionEncoderExtensionsによるエンコード
   └─ ラベル・分岐の解決

7. PE出力
   └─ PEBuilderでPEファイル生成
   └─ リソース埋め込み

8. 診断出力
   └─ エラー・警告の報告
```

### フローチャート

```mermaid
flowchart TD
    A[ILソースファイル] --> B[CILLexer]
    B --> C[PreprocessedTokenSource]
    C --> D[CILParser]
    D --> E[構文木]
    E --> F[GrammarVisitor]
    F --> G[EntityRegistry]
    G --> H[MetadataBuilder]
    H --> I[PEBuilder]
    I --> J[アセンブリ出力]

    F --> K[診断情報収集]
    K --> L[エラー報告]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-52-1 | 暗黙のObject継承 | クラスがextendsを指定しない場合、System.Objectを自動継承 | NoAutoInherit=false時 |
| BR-52-2 | エントリーポイント必須 | EXE出力時は.entrypointを持つメソッドが必須 | /exe指定時 |
| BR-52-3 | 重複定義エラー | 同名・同シグネチャのメソッドは定義不可 | 常時 |
| BR-52-4 | maxstack検証 | 指定されたmaxstackが実際の使用量以上であること | 常時 |

### IL命令エンコーディング

IL命令は1バイトまたは2バイトのオペコードとオペランドで構成される：
- 短形式命令（例: ldarg.0 → 0x02）
- 長形式命令（例: ldarg → 0xFE09 + 2バイトインデックス）

## データベース操作仕様

### 操作別データベース影響一覧

ilasmはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| Syntax Error | 構文エラー | 不正なIL構文 | ソースを修正 |
| Undefined Reference | 未定義参照 | 存在しない型・メソッドの参照 | 定義を追加または参照を修正 |
| Duplicate Definition | 重複定義 | 同名エンティティの重複 | 名前を変更 |
| Missing Entrypoint | エントリーポイント不在 | EXEで.entrypointなし | .entrypointを追加 |

### 診断メッセージ

診断メッセージは以下の情報を含む：
- ソースファイル名
- 行番号・列番号
- 重大度（Error/Warning/Info）
- メッセージ本文

## トランザクション仕様

ilasmはトランザクション処理を行わない。出力ファイルは成功時のみ書き込まれる。

## パフォーマンス要件

- 一般的なILソースファイル（数千行）は数秒以内にアセンブル完了
- 大規模ファイルでもメモリ使用量は入力サイズに比例

## セキュリティ考慮事項

- 入力ファイルの検証（パストラバーサル攻撃対策）
- 生成されたアセンブリの署名は別途ツールで実施

## 備考

本実装はANTLR4を使用したC#実装であり、従来のC++実装（src/coreclr/ilasm）とは別の新しい実装である。従来実装との完全な互換性を目指している。

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、ilasmで使用される主要なデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SourceText.cs | `src/tools/ilasm/src/ILAssembler/SourceText.cs` | ソースファイル表現 |
| 1-2 | Diagnostic.cs | `src/tools/ilasm/src/ILAssembler/Diagnostic.cs` | 診断情報の構造 |
| 1-3 | Options.cs | `src/tools/ilasm/src/ILAssembler/Options.cs` | コンパイルオプション |
| 1-4 | EntityRegistry.cs | `src/tools/ilasm/src/ILAssembler/EntityRegistry.cs` | 型・メソッド・フィールドの登録 |

**読解のコツ**: EntityRegistryはコンパイル中のシンボルテーブルとして機能し、前方参照の解決に使用される。

#### Step 2: エントリーポイントを理解する

コンパイル処理の開始点を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DocumentCompiler.cs | `src/tools/ilasm/src/ILAssembler/DocumentCompiler.cs` | メインのコンパイル処理 |
| 2-2 | ILCompilation.cs | `src/tools/ilasm/src/ILAssembler/ILCompilation.cs` | コンパイル結果のラッパー |

**主要処理フロー**:
- **16-57行目(DocumentCompiler.cs)**: `Compile`メソッドがコンパイル全体を統括
- **18-21行目**: ANTLRの入力ストリーム生成
- **22行目**: CILLexerによる字句解析
- **27-37行目**: プリプロセッサでのインクルード処理
- **45-46行目**: CILParserによる構文解析
- **47-48行目**: GrammarVisitorによる構文木の走査
- **50行目**: PEイメージの構築

#### Step 3: 字句・構文解析を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | PreprocessedTokenSource.cs | `src/tools/ilasm/src/ILAssembler/PreprocessedTokenSource.cs` | #include等のプリプロセス |
| 3-2 | GrammarVisitor.cs | `src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs` | 構文木のビジター実装 |

**主要処理フロー**:
- GrammarVisitorは`ICILVisitor<GrammarResult>`を実装
- 各構文ノードに対応するVisitメソッドが定義されている
- **73-101行目**: GrammarVisitorのフィールド定義と初期化

#### Step 4: メタデータ生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | MetadataExtensions.cs | `src/tools/ilasm/src/ILAssembler/MetadataExtensions.cs` | メタデータ生成ヘルパー |
| 4-2 | SignatureArg.cs | `src/tools/ilasm/src/ILAssembler/SignatureArg.cs` | 型シグネチャの処理 |
| 4-3 | TypeName.cs | `src/tools/ilasm/src/ILAssembler/TypeName.cs` | 型名のパースと表現 |

#### Step 5: IL命令エンコードを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | InstructionEncoderExtensions.cs | `src/tools/ilasm/src/ILAssembler/InstructionEncoderExtensions.cs` | IL命令のエンコード拡張 |
| 5-2 | BlobBuilderExtensions.cs | `src/tools/ilasm/src/ILAssembler/BlobBuilderExtensions.cs` | バイナリデータ構築 |

### プログラム呼び出し階層図

```
DocumentCompiler.Compile()
    │
    ├─ new AntlrInputStream()
    │
    ├─ new CILLexer()
    │
    ├─ new PreprocessedTokenSource()
    │      └─ includedDocumentLoader() [コールバック]
    │
    ├─ new CILParser()
    │      └─ parser.decls() → 構文木
    │
    ├─ new GrammarVisitor()
    │      ├─ _entityRegistry (EntityRegistry)
    │      ├─ _metadataBuilder (MetadataBuilder)
    │      └─ _pdbBuilder (MetadataBuilder)
    │
    ├─ result.Accept(visitor)
    │      └─ Visit*() メソッド群
    │
    └─ visitor.BuildImage()
           ├─ MetadataBuilder.Serialize()
           └─ PEBuilder.Build()
```

### データフロー図

```
[入力]                      [処理]                           [出力]

ILソースファイル     ───▶ CILLexer              ───▶ トークン列
  (.il)                    (字句解析)

トークン列           ───▶ CILParser             ───▶ 構文木
                          (構文解析)

構文木               ───▶ GrammarVisitor         ───▶ EntityRegistry
                          (意味解析)                    MetadataBuilder

EntityRegistry       ───▶ MetadataBuilder       ───▶ CLRメタデータ
MetadataBuilder           (メタデータ生成)

CLRメタデータ        ───▶ PEBuilder             ───▶ アセンブリ
                          (PE出力)                     (.dll/.exe)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DocumentCompiler.cs | `src/tools/ilasm/src/ILAssembler/DocumentCompiler.cs` | ソース | コンパイル処理のエントリー |
| ILCompilation.cs | `src/tools/ilasm/src/ILAssembler/ILCompilation.cs` | ソース | コンパイル結果ラッパー |
| GrammarVisitor.cs | `src/tools/ilasm/src/ILAssembler/GrammarVisitor.cs` | ソース | 構文木ビジター |
| PreprocessedTokenSource.cs | `src/tools/ilasm/src/ILAssembler/PreprocessedTokenSource.cs` | ソース | プリプロセッサ |
| EntityRegistry.cs | `src/tools/ilasm/src/ILAssembler/EntityRegistry.cs` | ソース | シンボルテーブル |
| Options.cs | `src/tools/ilasm/src/ILAssembler/Options.cs` | ソース | コンパイルオプション |
| SourceText.cs | `src/tools/ilasm/src/ILAssembler/SourceText.cs` | ソース | ソースファイル表現 |
| Diagnostic.cs | `src/tools/ilasm/src/ILAssembler/Diagnostic.cs` | ソース | 診断情報 |
| Location.cs | `src/tools/ilasm/src/ILAssembler/Location.cs` | ソース | ソース位置情報 |
| SourceSpan.cs | `src/tools/ilasm/src/ILAssembler/SourceSpan.cs` | ソース | ソース範囲 |
| TypeName.cs | `src/tools/ilasm/src/ILAssembler/TypeName.cs` | ソース | 型名表現 |
| SignatureArg.cs | `src/tools/ilasm/src/ILAssembler/SignatureArg.cs` | ソース | シグネチャ引数 |
| NameHelpers.cs | `src/tools/ilasm/src/ILAssembler/NameHelpers.cs` | ソース | 名前処理ヘルパー |
| MetadataExtensions.cs | `src/tools/ilasm/src/ILAssembler/MetadataExtensions.cs` | ソース | メタデータ拡張 |
| InstructionEncoderExtensions.cs | `src/tools/ilasm/src/ILAssembler/InstructionEncoderExtensions.cs` | ソース | IL命令エンコード |
| BlobBuilderExtensions.cs | `src/tools/ilasm/src/ILAssembler/BlobBuilderExtensions.cs` | ソース | バイナリ構築拡張 |
| StackExtensions.cs | `src/tools/ilasm/src/ILAssembler/StackExtensions.cs` | ソース | スタック操作拡張 |
| StringHelpers.cs | `src/tools/ilasm/src/ILAssembler/StringHelpers.cs` | ソース | 文字列処理ヘルパー |
| NamedElementList.cs | `src/tools/ilasm/src/ILAssembler/NamedElementList.cs` | ソース | 名前付き要素リスト |
| CIL.g4 | `src/tools/ilasm/src/ILAssembler/CIL.g4` | 文法 | ANTLR4文法定義 |
