# 機能設計書 32-同期WASMモジュール

## 概要

本ドキュメントは、webpackにおけるWebAssemblyモジュールの同期的な解析・コード生成・ランタイム読み込み機能について記述する。lib/wasm-sync/配下のモジュール群が、.wasmファイルの解析からJavaScriptグルーコードの生成、ランタイムでの同期読み込みまでを担当する。

### 本機能の処理概要

同期WASMモジュール機能は、WebAssembly（.wasm）ファイルをwebpackのモジュールシステムに統合し、同期的にインポート・実行できるようにする仕組みである。

**業務上の目的・背景**：WebAssemblyは高性能な計算処理をブラウザやNode.jsで実行するための標準規格である。従来のJavaScriptコードと同様にimport/requireで利用できるようにすることで、開発者がWebAssemblyを意識せずにパフォーマンスクリティカルな処理を実装できる。同期モードはwebpack 4からの互換性を維持するためのレガシーモード（WEBASSEMBLY_MODULE_TYPE_SYNC）である。

**機能の利用シーン**：experiments.syncWebAssembly設定が有効な場合に使用される。.wasmファイルをrequire()やimportで読み込む際に、同期的なモジュールとして扱う場面で利用される。

**主要な処理内容**：
1. .wasmバイナリの解析（@webassemblyjs/wasm-parserによるデコード）
2. import/export情報の抽出と依存関係の登録
3. JavaScriptグルーコード（インポートオブジェクト構築コード）の生成
4. WebAssemblyバイナリの変換（インポート名のマングリング等）
5. ランタイムでのWASMインスタンス化コードの生成

**関連システム・外部連携**：@webassemblyjs/astおよび@webassemblyjs/wasm-parserライブラリに依存する。ブラウザのWebAssembly APIを利用してモジュールをインスタンス化する。

**権限による制御**：特になし。experiments.syncWebAssembly設定により機能の有効/無効が制御される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 該当なし | - | WASMモジュール処理はビルド時のインフラ機能であり、特定の画面に直接関連しない |

## 機能種別

モジュール解析・変換・コード生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| source | Buffer | Yes | .wasmファイルのバイナリデータ | Buffer.isBuffer()で検証 |
| mangleImports | boolean | No | インポート名をマングリングするかどうか | WebAssemblyModulesPluginOptions |

### 入力データソース

- ファイルシステムから読み込まれた.wasmバイナリファイル（Buffer形式）
- webpack設定のexperiments.syncWebAssembly

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| JavaScript glue code | Source | WASMモジュールのインポートオブジェクトを構築するJavaScriptコード |
| WebAssembly binary | Source | 変換後のWASMバイナリ（インポート名変更等適用済み） |
| 依存関係情報 | Dependency[] | WebAssemblyImportDependency, WebAssemblyExportImportedDependency等 |
| エクスポート情報 | StaticExportsDependency | WASMモジュールが公開するエクスポートの一覧 |

### 出力先

バンドルファイル内にJavaScriptグルーコードとして出力。WASMバイナリは別ファイルとして出力される。

## 処理フロー

### 処理シーケンス

```
1. WASMバイナリの解析
   └─ @webassemblyjs/wasm-parserでデコード（ignoreCodeSection, ignoreDataSection有効）
2. import情報の抽出
   └─ ModuleImportノードを走査し、WebAssemblyImportDependencyを生成
3. export情報の抽出
   └─ ModuleExportノードを走査し、StaticExportsDependencyを生成
4. JS互換性チェック
   └─ i32/i64/f32/f64/externref以外の型はonlyDirectImportフラグを設定
5. JavaScriptグルーコード生成
   └─ WebAssemblyJavascriptGeneratorがインポートオブジェクト構築コードを出力
6. WASMバイナリ変換
   └─ WebAssemblyGeneratorがインポート名マングリング等の変換を適用
7. ランタイムコード生成
   └─ WasmChunkLoadingRuntimeModuleがWASMインスタンス化のランタイムコードを生成
```

### フローチャート

```mermaid
flowchart TD
    A[.wasmファイル読み込み] --> B[WebAssemblyParser.parse]
    B --> C[WASMバイナリデコード]
    C --> D[import/export情報抽出]
    D --> E{JS互換型?}
    E -->|Yes| F[通常のインポート依存を登録]
    E -->|No| G[onlyDirectImportフラグ設定]
    F --> H[StaticExportsDependency登録]
    G --> H
    H --> I[WebAssemblyJavascriptGenerator]
    I --> J[インポートオブジェクト構築コード生成]
    J --> K[WebAssemblyGenerator]
    K --> L[WASMバイナリ変換]
    L --> M[WasmChunkLoadingRuntimeModule]
    M --> N[ランタイム読み込みコード生成]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 初期チャンク禁止 | 同期WASMモジュールは初期チャンクに含められない（WebAssemblyInInitialChunkError） | afterChunks時に検証 |
| BR-02 | JS互換型制限 | i32, i64, f32, f64, externref以外の型パラメータはJS非互換としてマーク | インポート/エクスポート解析時 |
| BR-03 | ESMフラグ | WASMモジュールはstrict=true, exportsType="namespace"として扱う | パース時 |
| BR-04 | インポート名マングリング | mangleImportsオプションが有効の場合、WASMインポート名を短縮 | コード生成時 |

### 計算ロジック

JS互換性チェック: signature.paramsおよびsignature.resultsの各型がJS_COMPAT_TYPES（i32, i64, f32, f64, externref）に含まれるかを検査する。非互換型が見つかった場合、そのインポートはonlyDirectImport=trueとなりJavaScript経由の直接呼び出しが制限される。

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

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

該当なし（ビルド時処理のためDB操作は存在しない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | WebAssemblyParser入力がBufferでない場合 | "WebAssemblyParser input must be a Buffer"エラーをスロー |
| - | WebAssemblyInInitialChunkError | 同期WASMモジュールが初期チャンクに含まれる場合 | エラーメッセージで初期チャンクからの除外を案内 |
| - | UnsupportedWebAssemblyFeatureError | サポートされていないWASM機能が使用されている場合 | エラーメッセージで非対応機能を通知 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- WASMバイナリのパース時にignoreCodeSection, ignoreDataSectionを有効にし、不要なセクションの解析をスキップして高速化
- ignoreCustomNameSectionにより名前ルックアップを省略

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

- WebAssemblyバイナリの解析は@webassemblyjs/wasm-parserライブラリに委譲しており、不正なバイナリによる脆弱性はライブラリ側のセキュリティに依存する

## 備考

- webpack 6でwasm-syncフォルダ全体が削除予定（WasmChunkLoadingRuntimeModule.js 23行目のTODOコメントに記載）
- 非同期WASMモジュール（wasm-async）が推奨される方式

---

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

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

### 推奨読解順序

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

WASMモジュールの依存関係を表すデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | WebAssemblyParser.js | `lib/wasm-sync/WebAssemblyParser.js` | 22行目: JS_COMPAT_TYPESの定義（i32, i64, f32, f64, externref） |
| 1-2 | WebAssemblyImportDependency.js | `lib/dependencies/WebAssemblyImportDependency.js` | WASMインポートを表す依存クラス |
| 1-3 | WebAssemblyExportImportedDependency.js | `lib/dependencies/WebAssemblyExportImportedDependency.js` | WASMエクスポートの再インポートを表す依存クラス |

**読解のコツ**: @webassemblyjs/astのトラバーサル関数（t.traverse）はAST訪問パターンを使用する。ModuleImport/ModuleExportはWASMバイナリ内のセクションに対応するノード型である。

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

WebAssemblyModulesPluginが全体の統合ポイントとなる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | WebAssemblyModulesPlugin.js | `lib/wasm-sync/WebAssemblyModulesPlugin.js` | 51-100行目: apply()でパーサ・ジェネレータの登録、依存ファクトリの設定 |

**主要処理フロー**:
1. **55-58行目**: WebAssemblyImportDependencyのファクトリ登録
2. **65-71行目**: WEBASSEMBLY_MODULE_TYPE_SYNC用パーサの登録
3. **73-80行目**: WEBASSEMBLY_MODULE_TYPE_SYNC用ジェネレータの登録（JavascriptGenerator + WebAssemblyGenerator）

#### Step 3: パーサ処理を理解する

WebAssemblyParserがWASMバイナリを解析する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | WebAssemblyParser.js | `lib/wasm-sync/WebAssemblyParser.js` | 65-80行目: parse()メソッドでBufferをデコードし依存関係を抽出 |

**主要処理フロー**:
- **71-73行目**: Buffer入力の検証
- **78-80行目**: buildInfo.strict=true, buildMeta.exportsType="namespace"のESMフラグ設定
- **57-63行目**: decoderOptsでignoreCodeSection, ignoreDataSection, ignoreCustomNameSectionを有効化

#### Step 4: ランタイムコード生成を理解する

WasmChunkLoadingRuntimeModuleがランタイムでのWASMインスタンス化コードを生成する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | WasmChunkLoadingRuntimeModule.js | `lib/wasm-sync/WasmChunkLoadingRuntimeModule.js` | 32-48行目: getAllWasmModulesで非同期チャンク内のWASMモジュールを収集 |
| 4-2 | WebAssemblyUtils.js | `lib/wasm-sync/WebAssemblyUtils.js` | WASMの依存関係ユーティリティ |
| 4-3 | WasmFinalizeExportsPlugin.js | `lib/wasm-sync/WasmFinalizeExportsPlugin.js` | WASMエクスポートの最終化処理 |

**主要処理フロー**:
- **61-77行目**: generateImportObjectでWASMインポートオブジェクトのJavaScriptコードを構築

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

```
WebAssemblyModulesPlugin.apply()
    |
    +-- normalModuleFactory.hooks.createParser (WEBASSEMBLY_MODULE_TYPE_SYNC)
    |      +-- WebAssemblyParser
    |             +-- @webassemblyjs/wasm-parser.decode()
    |             +-- t.traverse() [AST走査]
    |             +-- WebAssemblyImportDependency (生成)
    |             +-- StaticExportsDependency (生成)
    |
    +-- normalModuleFactory.hooks.createGenerator (WEBASSEMBLY_MODULE_TYPE_SYNC)
    |      +-- WebAssemblyJavascriptGenerator [JSグルーコード]
    |      +-- WebAssemblyGenerator [WASMバイナリ変換]
    |
    +-- compilation.hooks.renderManifest
    |      +-- WASMバイナリアセット出力
    |
    +-- compilation.hooks.afterChunks
           +-- WebAssemblyInInitialChunkError検証
```

### データフロー図

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

.wasmバイナリ ---------> WebAssemblyParser           ---> 依存関係情報
  (Buffer)                |                              (Import/Export)
                          v
                    WebAssemblyJavascriptGenerator   ---> JSグルーコード
                          |                              (importObject構築)
                          v
                    WebAssemblyGenerator             ---> 変換済みWASMバイナリ
                          |                              (.wasmファイル)
                          v
                    WasmChunkLoadingRuntimeModule     ---> ランタイムコード
                                                         (WebAssembly.instantiate呼び出し)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| WebAssemblyModulesPlugin.js | `lib/wasm-sync/WebAssemblyModulesPlugin.js` | ソース | 同期WASMモジュール機能の統合プラグイン |
| WebAssemblyParser.js | `lib/wasm-sync/WebAssemblyParser.js` | ソース | WASMバイナリの解析・依存関係抽出 |
| WebAssemblyJavascriptGenerator.js | `lib/wasm-sync/WebAssemblyJavascriptGenerator.js` | ソース | JavaScriptグルーコードの生成 |
| WebAssemblyGenerator.js | `lib/wasm-sync/WebAssemblyGenerator.js` | ソース | WASMバイナリの変換処理 |
| WasmChunkLoadingRuntimeModule.js | `lib/wasm-sync/WasmChunkLoadingRuntimeModule.js` | ソース | WASMランタイム読み込みコードの生成 |
| WebAssemblyUtils.js | `lib/wasm-sync/WebAssemblyUtils.js` | ソース | WASM関連ユーティリティ |
| WasmFinalizeExportsPlugin.js | `lib/wasm-sync/WasmFinalizeExportsPlugin.js` | ソース | WASMエクスポートの最終化 |
| WebAssemblyInInitialChunkError.js | `lib/wasm-sync/WebAssemblyInInitialChunkError.js` | ソース | 初期チャンクエラー定義 |
| UnsupportedWebAssemblyFeatureError.js | `lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js` | ソース | 非サポート機能エラー定義 |
