# バッチ設計書 70-js2c.cc

## 概要

本ドキュメントは、Node.jsプロジェクトにおけるJavaScript to C++変換ツール（js2c.cc）の設計仕様を記載したものである。

### 本バッチの処理概要

js2c.ccは、Node.jsの組み込みJavaScriptモジュールをC++コードに変換するビルドツールである。lib/ディレクトリとdeps/ディレクトリのJavaScriptファイルを読み込み、それらをC++の静的データとして埋め込んだソースファイル（node_javascript.cc）を生成する。これにより、Node.jsの組み込みモジュールがバイナリに直接コンパイルされ、ファイルシステムからの読み込みなしに利用できるようになる。

**業務上の目的・背景**：Node.jsには、fs、http、pathなど多数の組み込みモジュールがJavaScriptで実装されている。これらをバイナリに埋め込むことで、起動時のファイルI/Oを削減し、配布サイズの最適化と起動時間の短縮を実現する。また、ソースコードを直接バイナリに含めることで、依存ファイルの破損や改ざんリスクを軽減できる。

**バッチの実行タイミング**：Node.jsのビルドプロセス中に自動実行される。make/ninjaからGYPビルドシステム経由で呼び出される。

**主要な処理内容**：
1. コマンドライン引数の解析（出力ファイルパス、入力ディレクトリ/ファイル）
2. 指定ディレクトリからJavaScript（.js、.mjs）ファイルを再帰的に検索
3. config.gypiファイルの読み込みとJSON化
4. 各ファイルのエンコーディング変換（ASCII、Latin-1、UTF-16）
5. C++ソースコード生成（静的リソース定義、BuiltinSourceMap初期化子、ExternalReference登録）
6. 変更がある場合のみ出力ファイルを更新

**前後の処理との関連**：GYPビルドシステムからビルド前に呼び出される。生成されたnode_javascript.ccはNode.jsのコンパイル時にリンクされる。

**影響範囲**：Node.jsの組み込みモジュール全体。ビルド成果物のサイズとNode.js起動性能に影響する。

## バッチ種別

コード生成（ビルドツール）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | ビルド時（随時） |
| 実行時刻 | N/A |
| 実行曜日 | N/A |
| 実行日 | N/A |
| トリガー | GYPビルドシステム / make / ninja |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| C++17対応コンパイラ | ビルドにC++17が必要 |
| simdutf ライブラリ | UTF変換に使用 |
| libuv | ファイルI/O操作に使用 |
| 入力ファイル | lib/、deps/ディレクトリにJSファイルが存在すること |
| config.gypi | ビルド設定ファイルが存在すること |

### 実行可否判定

1. コマンドライン引数が最低2つ（出力ファイル、入力パス）あることを確認
2. 入力パスが有効なディレクトリまたはファイルであることを確認
3. config.gypiが入力に含まれていることを確認

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| --verbose | フラグ | No | false | 詳細ログを出力 |
| --root | パス | No | カレントディレクトリ | プロジェクトルートディレクトリ |
| 第1位置引数 | パス | Yes | なし | 出力ファイルパス（例: out/Release/gen/node_javascript.cc） |
| 第2位置引数以降 | パス | Yes | なし | 入力ディレクトリまたはファイル（lib、deps、config.gypi） |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| lib/**/*.js | JavaScript | Node.js標準ライブラリのJSファイル |
| lib/**/*.mjs | ES Module | Node.js標準ライブラリのESモジュールファイル |
| deps/**/*.js | JavaScript | 依存ライブラリのJSファイル |
| config.gypi | GYP設定（Python風） | ビルド設定ファイル（JSON化して埋め込み） |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 指定出力ファイル | C++ソース | 組み込みモジュールを含むC++コード |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | 引数で指定（通常 node_javascript.cc） |
| 出力先 | out/{Release|Debug}/gen/ |
| 文字コード | ASCII（C++ソースとして） |
| フォーマット | C++17準拠のソースコード |

## 処理フロー

### 処理シーケンス

```
1. コマンドライン解析
   └─ --verbose、--root オプションの処理
   └─ 出力パスと入力パスの分離
2. プロジェクトルートへの移動
   └─ --rootが指定されている場合はuv_chdirで移動
3. ファイル収集
   └─ 入力パスがディレクトリの場合: SearchFilesで再帰的に.js/.mjsを検索
   └─ 入力パスがファイルの場合: 拡張子を確認してリストに追加
4. ファイルマップの構築
   └─ .js、.mjs、.gypiファイルを分類
5. ファイルリストのソート
   └─ ファイル名でソート（決定的な出力のため）
6. 各ファイルの処理
   └─ ファイル読み込み（ReadFileSync）
   └─ ファイルIDの生成（GetFileId: パスから拡張子とプレフィックスを除去）
   └─ 変数名の生成（GetVariableName: /、-、.を_に置換）
   └─ エンコーディング判定（ASCII、Latin-1、UTF-16）
   └─ C++データ定義の生成（GetDefinition）
7. config.gypiの処理
   └─ コメント除去（StripComments）
   └─ JSON化（JSONify）
   └─ C++データとして埋め込み
8. 出力コード生成
   └─ kTemplateを使用してC++ソースを生成
   └─ 定義、初期化子、登録コードを結合
9. 差分チェックと書き込み
   └─ WriteIfChanged: 変更がある場合のみ書き込み
```

### フローチャート

```mermaid
flowchart TD
    A[js2c開始] --> B[コマンドライン解析]
    B --> C{--root指定?}
    C -->|あり| D[uv_chdirでディレクトリ移動]
    C -->|なし| E[入力パス処理]
    D --> E
    E --> F{入力はディレクトリ?}
    F -->|はい| G[SearchFilesで再帰検索]
    F -->|いいえ| H[ファイルをリストに追加]
    G --> I[ファイルマップ構築]
    H --> I
    I --> J[ファイルリストソート]
    J --> K[各JSファイル処理ループ]
    K --> L[ファイル読み込み]
    L --> M[ファイルID/変数名生成]
    M --> N{エンコーディング判定}
    N -->|ASCII| O[ASCII用定義生成]
    N -->|Latin-1| P[Latin-1用定義生成]
    N -->|UTF-16| Q[UTF-16用定義生成]
    O --> R[次のファイルへ]
    P --> R
    Q --> R
    R --> K
    K -->|完了| S[config.gypi処理]
    S --> T[kTemplateでC++コード生成]
    T --> U{既存ファイルと差分あり?}
    U -->|あり| V[ファイル書き込み]
    U -->|なし| W[スキップ]
    V --> X[終了]
    W --> X
```

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

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

本バッチはデータベースを使用しない。

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| N/A | N/A | N/A | データベース操作なし |

### テーブル別操作詳細

N/A

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | 引数エラー | 引数数が不足 | 正しい引数でjs2cを実行 |
| 1 | ディレクトリエラー | --rootで指定したディレクトリが存在しない | 正しいパスを指定 |
| 1 | ファイルエラー | config.gypiが入力に含まれていない | config.gypiを入力に追加 |
| 1 | ファイルエラー | 入力ファイルが読み込めない | ファイルパスとアクセス権限を確認 |
| 1 | 拡張子エラー | サポートされていない拡張子のファイル | .js、.mjs、.gypiのみサポート |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（自動リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

1. エラーメッセージを確認し、原因を特定
2. 入力ファイル/ディレクトリのパスが正しいことを確認
3. config.gypiが入力に含まれていることを確認
4. ファイルのアクセス権限を確認
5. ディスク容量を確認（出力ファイル書き込み用）

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A |
| コミットタイミング | N/A |
| ロールバック条件 | N/A |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 数百ファイル/実行 |
| 目標処理時間 | 10秒以内 |
| メモリ使用量上限 | 1GB以下 |

## 排他制御

同一出力ファイルに対する同時実行は不可。ビルドシステムが排他制御を管理。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| デバッグログ | --verbose時 | ファイル読み込み/書き込み操作の詳細 |
| デバッグログ | --verbose時 | エンコーディング判定結果 |
| エラーログ | エラー発生時 | システムコールエラーとファイル名 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| ビルドエラー | 1回 | ビルドシステム |

## 備考

- C++17の機能（std::string_view、if constexpr等）を使用
- simdutfライブラリでUTF-8からLatin-1/UTF-16への高速変換を実装
- undiciモジュールの特殊文字（' -> '）を簡略化してLatin-1に収める最適化あり
- NODE_JS2C_USE_STRING_LITERALS定義で配列リテラルではなく文字列リテラルとして出力可能（gcc/clangでのコンパイル高速化）
- WriteIfChangedにより、内容が変わらない場合は書き込みをスキップ（不要な再コンパイルを防止）
- lib/eslint.config_partial.mjsは除外される（eslint設定ファイルのため）
- 生成されるC++コードの主要構造:
  - 各ファイルの静的データ定義（uint8_t/uint16_t配列またはraw文字列リテラル）
  - StaticExternalOneByteResource/StaticExternalTwoByteResourceインスタンス
  - BuiltinSourceMapの初期化子
  - ExternalReferenceRegistry登録関数
