# 機能設計書 119-nimhcr

## 概要

本ドキュメントは、Nim標準ライブラリの`nimhcr`（Nimホットコードリロード）モジュールの機能設計について記載する。このモジュールはネイティブターゲットでのホットコードリロード機能を提供する。

### 本機能の処理概要

nimhcrモジュールは、プログラム実行中にコードを動的に再ロードする機能を提供する。開発中のイテレーション時間を短縮し、アプリケーションを再起動せずにコード変更を反映できる。

**業務上の目的・背景**：開発中の高速なイテレーションサイクルを実現するため、コード変更後にアプリケーション全体を再起動せずに変更を反映できる機能が必要となる。特にゲーム開発やUIアプリケーションの開発において、状態を維持したままコードを更新できることは生産性を大幅に向上させる。

**機能の利用シーン**：
- 開発中のUIの調整
- ゲームロジックのイテレーション
- サーバーアプリケーションのホットパッチ
- インタラクティブな開発環境

**主要な処理内容**：
1. `hcrInit` - HCRランタイムの初期化
2. `hcrRegisterProc` - プロシージャの登録
3. `hcrRegisterGlobal` - グローバル変数の登録
4. `hcrPerformCodeReload` - コードのリロード実行
5. `hcrAddEventHandler` - リロードイベントハンドラの登録

**関連システム・外部連携**：
- 動的ライブラリ（DLL/dylib/so）
- Nimランタイムライブラリ（nimrtl）
- ファイルシステム（タイムスタンプ監視）

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 開発時に使用するランタイム機能 |

## 機能種別

動的ロード / 開発支援

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| module | cstring | Yes | モジュール名 | - |
| name | cstring | Yes | シンボル名 | - |
| fn | pointer | Yes | 関数ポインタ | nil不可 |
| size | Natural | Yes | グローバルのサイズ | > 0 |
| gcMarker | HcrGcMarkerProc | No | GCマーカー | nil可 |

### 入力データソース

コンパイル時に生成されるモジュール情報、動的ライブラリファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| pointer | pointer | 登録されたシンボルの永続アドレス |
| bool | bool | 初期化が必要かどうか |

### 出力先

メモリ上のトランポリンテーブル、グローバル変数領域

## 処理フロー

### 処理シーケンス

```
1. メインモジュールがHCRランタイムをロード
   └─ nimhcr.dll/dylib/soをロード

2. hcrInit()で初期化
   └─ モジュールインポートツリーの構築
   └─ 依存モジュールのDFS順ロード

3. 各モジュールの初期化パス
   └─ HcrInit - HCRポインタ初期化
   └─ HcrCreateTypeInfos - 型情報グローバル作成
   └─ DatInit - データ初期化 + プロシージャ/グローバル登録
   └─ Init - トップレベルコード実行

4. hcrPerformCodeReload()でリロード
   └─ タイムスタンプを確認して変更モジュール検出
   └─ beforeCodeReloadハンドラ実行
   └─ DLLをアンロード→コピー→再ロード
   └─ 初期化パスを再実行
   └─ afterCodeReloadハンドラ実行
   └─ 古いシンボルをクリーンアップ

5. シンボル管理
   └─ プロシージャ: トランポリン経由で呼び出し
   └─ グローバル: ヒープ上に永続化
```

### フローチャート

```mermaid
flowchart TD
    A[アプリ起動] --> B[HCRランタイムロード]
    B --> C[hcrInit]
    C --> D[依存モジュールをDFS順でロード]
    D --> E[各モジュール初期化]
    E --> F[アプリ実行中]
    F --> G{コードリロード要求?}
    G -->|No| F
    G -->|Yes| H[hcrPerformCodeReload]
    H --> I[タイムスタンプ確認]
    I --> J{変更あり?}
    J -->|No| F
    J -->|Yes| K[beforeHandler実行]
    K --> L[DLL再ロード]
    L --> M[再初期化]
    M --> N[afterHandler実行]
    N --> O[古いシンボルクリーンアップ]
    O --> F
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-119-01 | メインモジュール不変 | メインモジュールはリロード不可 | 常時 |
| BR-119-02 | コールスタック制約 | リロード時にリロード対象の関数がスタック上にあってはならない | リロード時 |
| BR-119-03 | グローバル永続化 | グローバル変数は初回のみ初期化、以降は状態維持 | 常時 |
| BR-119-04 | トップレベル初回のみ | トップレベルコードは初回ロード時のみ実行 | 常時 |
| BR-119-05 | 型レイアウト不変 | メモリレイアウトの変更は検出されない | 注意 |

### 計算ロジック

トランポリン（ジャンプテーブル）:
- x86: 5バイトの相対ジャンプ命令
- x64: 6バイトの間接ジャンプ + 8バイトのアドレス

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

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | クラッシュ | リロード対象関数がスタック上 | リロードタイミングを調整 |
| - | ライブラリエラー | DLLロード失敗 | ビルドを確認 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- トランポリン経由の関数呼び出しオーバーヘッド
- リロード時のDLLコピー処理

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

- 開発環境専用（本番環境での使用は非推奨）
- 任意コード実行のリスク

## 備考

- `--hotCodeReloading:on`コンパイルオプションが必要
- ARM対応は未実装
- JavaScript向けは限定的サポート

---

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

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

### 推奨読解順序

#### Step 1: 概要と設計思想を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | nimhcr.nim | `lib/nimhcr.nim` | 詳細設計コメント（13-201行目） |
| 1-2 | nimhcr.nim | `lib/nimhcr.nim` | 型定義（213-216行目） |

**読解のコツ**: 冒頭の長いコメントが設計思想、制約、TODOを詳細に説明している。まずこれを通読すること。

#### Step 2: 型とデータ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | nimhcr.nim | `lib/nimhcr.nim` | ジャンプ命令構造体（240-248行目） |
| 2-2 | nimhcr.nim | `lib/nimhcr.nim` | ProcSym/GlobalVarSym（290-298行目） |
| 2-3 | nimhcr.nim | `lib/nimhcr.nim` | ModuleDesc（300-308行目） |

**主要処理フロー**:
- **240-248行目**: ShortJumpInstruction/LongJumpInstructionでトランポリン実装
- **290-298行目**: シンボル管理構造体
- **300-308行目**: モジュール管理構造体

#### Step 3: 登録関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | nimhcr.nim | `lib/nimhcr.nim` | hcrRegisterProc（334-354行目） |
| 3-2 | nimhcr.nim | `lib/nimhcr.nim` | hcrGetProc（356-358行目） |
| 3-3 | nimhcr.nim | `lib/nimhcr.nim` | hcrRegisterGlobal（360-386行目） |
| 3-4 | nimhcr.nim | `lib/nimhcr.nim` | hcrGetGlobal（388-390行目） |

#### Step 4: 初期化フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | nimhcr.nim | `lib/nimhcr.nim` | loadDll（423-448行目） |
| 4-2 | nimhcr.nim | `lib/nimhcr.nim` | initHcrData等（455-472行目） |
| 4-3 | nimhcr.nim | `lib/nimhcr.nim` | recursiveDiscovery（477-498行目） |
| 4-4 | nimhcr.nim | `lib/nimhcr.nim` | initModules（500-519行目） |
| 4-5 | nimhcr.nim | `lib/nimhcr.nim` | hcrInit（521-537行目） |

#### Step 5: リロード処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | nimhcr.nim | `lib/nimhcr.nim` | hcrReloadNeeded（543-547行目） |
| 5-2 | nimhcr.nim | `lib/nimhcr.nim` | hcrPerformCodeReload（549-603行目） |
| 5-3 | nimhcr.nim | `lib/nimhcr.nim` | hcrAddEventHandler（605-607行目） |

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

```
メインモジュール
    │
    ├─ nimhcr.dllをロード
    │
    └─ hcrInit(moduleList, main, sys, datInit, handle, getProcAddr)
           │
           ├─ recursiveDiscovery(imports)
           │      └─ loadDll(module)
           │             └─ copyFileWithPermissions
           │             └─ loadLib
           │             └─ HcrGetImportedModules
           │
           └─ initModules()
                  ├─ initHcrData (HcrInit000)
                  ├─ initTypeInfoGlobals (HcrCreateTypeInfos)
                  ├─ initPointerData (DatInit000)
                  │      ├─ hcrRegisterProc
                  │      └─ hcrRegisterGlobal
                  └─ initGlobalScope (Init000)
```

### データフロー図

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

ソースコード変更 ─▶ リビルド ──────▶ 新しいDLL
        │
hcrPerformCodeReload
        │
        ▼
タイムスタンプ比較 ─▶ 変更検出
        │
        ▼
DLLコピー・再ロード ─▶ 新しいシンボル
        │
        ▼
トランポリン更新 ───▶ 関数呼び出しが新コードへ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| nimhcr.nim | `lib/nimhcr.nim` | ソース | HCRランタイム |
| hotcodereloading.nim | `lib/std/hotcodereloading.nim` | ソース | ユーザー向けAPI |
| reservedmem.nim | `lib/std/reservedmem.nim` | ソース | ジャンプテーブル用メモリ |
