# 機能設計書 62-WASIワークロード

## 概要

本ドキュメントは、.NET RuntimeにおけるWASIワークロード（WASI Workload）機能の設計仕様を定義する。WASIワークロードは、WebAssembly System Interface（WASI）に準拠した.NETアプリケーションの開発・ビルド・実行をサポートするための開発ツールキット群であり、.NETコードをWASIランタイム（Wasmtime等）で実行可能なWebAssemblyモジュールにコンパイルする機能を提供する。

### 本機能の処理概要

WASIワークロードは、.NET開発者がC#で記述したコードをWebAssembly System Interface（WASI）規格に準拠したWebAssemblyモジュールとして出力し、様々なWASIランタイム環境で実行可能にする機能である。

**業務上の目的・背景**：WebAssembly（Wasm）はブラウザ外でも動作可能なポータブルなバイナリフォーマットとして注目されている。WASI（WebAssembly System Interface）は、WebAssemblyがファイルシステム、ネットワーク、時計などのシステムリソースにアクセスするための標準化されたインターフェースを提供する。WASIワークロードにより、.NET開発者はサーバーサイドやエッジコンピューティング環境でWebAssemblyの利点（サンドボックス化、ポータビリティ、セキュリティ）を活用したアプリケーションを開発できる。

**機能の利用シーン**：
- サーバーレスコンピューティング環境でのWasmモジュール実行
- エッジコンピューティングでの軽量ランタイム実行
- プラグインシステムやサンドボックス実行環境の構築
- マルチプラットフォーム対応のコマンドラインツール開発
- WASIp2対応のHTTPサーバー/クライアントアプリケーション

**主要な処理内容**：
1. MonoランタイムベースのWASI向けWebAssemblyモジュール生成
2. AOT（Ahead-of-Time）コンパイルによるネイティブWasmコード生成
3. WASI Preview 2（wasip2）対応のHTTP通信サポート
4. 非同期イベントループ（WasiEventLoop）による非同期処理サポート
5. WASIp2ソケットおよびHTTPインターフェースの統合

**関連システム・外部連携**：
- WASI SDK（clang、wasm-ldなどのツールチェーン）
- Wasmtimeランタイム（WASI参照実装）
- WASIp2（WASI Preview 2）仕様に基づくHTTP、ソケットインターフェース
- Mono AOTコンパイラ（LLVMベースの事前コンパイル）

**権限による制御**：本機能は開発ツールであり、実行時の権限はWASIのケーパビリティモデルに基づく。ファイルシステムアクセス、ネットワーク接続等はWASIランタイムの設定で制御される。

## 関連画面

本機能は開発ツールであり、直接的なUI画面は提供しない。コンソールアプリケーションとして実行される。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | Wasi.Console.Sample | 参照サンプル | 基本的なWASIコンソールアプリケーション |
| - | Wasip2.Http.Console.Sample | 参照サンプル | WASIp2 HTTP対応アプリケーション |
| - | Wasip2.Sockets.Console.Sample | 参照サンプル | WASIp2ソケット対応アプリケーション |

## 機能種別

ビルドタスク / 開発ツールキット / ランタイムサポート

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| RuntimeIdentifier | string | Yes | ターゲットRID（wasi-wasm固定） | "wasi-wasm" |
| TargetFramework | string | Yes | ターゲットフレームワーク | net10.0以降 |
| OutputType | string | Yes | 出力タイプ | Exe/Library |
| PublishTrimmed | bool | No | ILトリミングを有効化 | true/false（推奨：true） |
| RunAOTCompilation | bool | No | AOTコンパイルを有効化 | true/false |
| WasmBuildNative | bool | No | ネイティブビルドを強制 | true/false |
| WasmSingleFileBundle | bool | No | 単一ファイルバンドル | true/false |
| InvariantGlobalization | bool | No | グローバリゼーション無効化 | true/false |
| _WasiNeedsHttp | bool | No | HTTP依存性を示すフラグ | true/false |
| _WasiDebugger | bool | No | デバッガー接続を有効化 | true/false |

### 入力データソース

- MSBuildプロジェクトファイル（.csproj）からのビルドプロパティ
- 環境変数（WASI_SDK_PATH）
- NuGetパッケージとしてインストールされたWASIランタイムパック

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| WebAssemblyモジュール | .wasm | WASI対応のWebAssemblyバイナリ |
| dotnet.wasm | .wasm | .NETランタイムのWasmモジュール |
| AppBundle | ディレクトリ | 実行に必要なすべてのファイルを含むバンドル |

### 出力先

- Wasmモジュール：`{PublishDir}/AppBundle/{AssemblyName}.wasm`
- ランタイムファイル：`{PublishDir}/AppBundle/`配下

## 処理フロー

### 処理シーケンス

```
1. プロジェクト設定の解析
   └─ TargetFramework、RuntimeIdentifierの検証
2. 依存関係の解決
   └─ WASIランタイムパック、WASI SDKの確認
3. ILアセンブリのビルド
   └─ 通常の.NETビルドプロセス
4. ILトリミング（PublishTrimmed=true時）
   └─ 未使用コードの除去
5. AOTコンパイル（RunAOTCompilation=true時）
   └─ MonoAOTCompilerによるWasm生成
6. ネイティブビルド（WasmBuildNative=true時）
   └─ WASI SDKを使用したネイティブコードリンク
7. AppBundleの生成
   └─ 実行に必要なファイルをバンドル
8. 実行（dotnet run時）
   └─ Wasmtimeで実行
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[プロジェクト設定解析]
    B --> C[依存関係解決]
    C --> D{WASI SDK存在?}
    D -->|No| E[エラー終了]
    D -->|Yes| F[ILビルド]
    F --> G{PublishTrimmed?}
    G -->|Yes| H[ILトリミング]
    G -->|No| I{AOT?}
    H --> I
    I -->|Yes| J[AOTコンパイル]
    I -->|No| K{WasmBuildNative?}
    J --> K
    K -->|Yes| L[ネイティブビルド]
    K -->|No| M[AppBundle生成]
    L --> M
    M --> N[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | WASI SDK必須 | ビルドにはWASI SDKが必要 | 常時 |
| BR-002 | RuntimeIdentifier固定 | wasi-wasmのみサポート | 常時 |
| BR-003 | HTTP依存性フラグ | wasi:http依存時は_WasiNeedsHttp=true | HTTP機能使用時 |
| BR-004 | トリミング推奨 | PublishTrimmed=trueでサイズ最適化 | 本番デプロイ時推奨 |

### 計算ロジック

特になし。ビルドプロセスはMSBuildターゲットの依存関係に基づいて実行される。

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

本機能はデータベースを使用しない。

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| WASI001 | Exception | WASI_SDK_PATHが未設定 | 環境変数を設定 |
| WASI002 | BuildError | RuntimeIdentifierがwasi-wasm以外 | wasi-wasmを指定 |
| WASI003 | BuildError | TargetFrameworkが古すぎる | net10.0以降を使用 |
| WASI004 | PlatformNotSupportedException | 非対応APIの呼び出し | WASI対応APIを使用 |

### リトライ仕様

本機能にリトライ機能は実装されていない。ビルドエラーは即座に報告される。

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

該当なし（ファイルシステム操作のみ）

## パフォーマンス要件

- AOTコンパイルにより起動時間を短縮可能
- トリミングによりWasmモジュールサイズを最適化
- WasiEventLoopによる効率的な非同期処理

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

- WASIケーパビリティモデルによるサンドボックス実行
- ファイルシステム、ネットワークアクセスはWASIランタイムで制御
- メモリ安全性はWebAssemblyの仕様で保証

## 備考

- 対応WASIバージョン：WASI Preview 2（wasip2）
- サポートプラットフォーム：Windows（win-x64/arm64）、Linux（linux-x64/arm64/musl-x64/musl-arm64）、macOS（osx-x64/arm64）
- 推奨ランタイム：Wasmtime
- 実験的機能としての提供（wasi-experimental workload）

---

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

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

### 推奨読解順序

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

まず、WASIイベントループとHTTPハンドラのデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | WasiEventLoop.cs | `src/libraries/System.Private.CoreLib/src/System/Threading/Wasi/WasiEventLoop.cs` | PollableHolderクラス（196-252行目）でPollable管理、PollHookクラス（254-289行目）でポーリングフック管理 |
| 1-2 | WasiHttpHandler.cs | `src/libraries/System.Net.Http/src/System/Net/Http/WasiHttpHandler/WasiHttpHandler.cs` | WasiRequestWrapperクラス（22-143行目）でHTTPリクエストのライフサイクル管理 |

**読解のコツ**: WASIは非同期I/Oに「Pollable」という概念を使用する。PollableはWASIランタイムが提供する待機可能なオブジェクトで、.NETのTaskと統合される。

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

イベントループの起動と非同期処理の統合を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | WasiEventLoop.cs | `src/libraries/System.Private.CoreLib/src/System/Threading/Wasi/WasiEventLoop.cs` | PollWasiEventLoopUntilResolved（52-73行目）がメイン非同期ループ |

**主要処理フロー**:
1. **52-73行目**: PollWasiEventLoopUntilResolved<T>で非同期タスクが完了するまでイベントループを実行
2. **75-95行目**: PollWasiEventLoopUntilResolvedVoidでvoid返却タスク用の同等処理
3. **97-104行目**: ScheduleCheckでポーリングチェックをスケジュール
4. **106-193行目**: CheckPollablesで全ての登録されたPollableをチェックし、完了したものを解決

#### Step 3: HTTP通信の実装を理解する

WASIp2 HTTP仕様に基づくHTTPクライアント実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | WasiHttpHandler.cs | `src/libraries/System.Net.Http/src/System/Net/Http/WasiHttpHandler/WasiHttpHandler.cs` | WasiHttpHandlerクラス（145-263行目）がHttpMessageHandlerの実装 |
| 3-2 | WasiRequestWrapper | 同上 | SendRequestAsyncメソッド（29-79行目）でリクエスト送信フロー |

**主要処理フロー**:
- **29-43行目**: リクエストヘッダー変換、メソッド/スキーム/オーソリティ設定
- **45-53行目**: コンテンツ送信を非同期で開始、OutgoingHandlerでリクエスト発行
- **58-68行目**: レスポンス受信とHttpResponseMessageの構築
- **81-115行目**: FutureIncomingResponseのポーリングによるレスポンス待機

#### Step 4: ビルド設定とテストを理解する

ワークロードマニフェストとビルドテストの構成を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | WorkloadManifest.json.in | `src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.json.in` | wasi-experimentalワークロード定義（27-36行目） |
| 4-2 | BuildTestBase.cs | `src/mono/wasi/Wasi.Build.Tests/BuildTestBase.cs` | WASIビルドテストの基盤クラス |

**主要処理フロー**:
- **WorkloadManifest 27-36行目**: wasi-experimentalワークロードが含むパック（WASI SDK、ランタイム、テンプレート、AOTクロスコンパイラ）
- **BuildTestBase 66-68行目**: WASI_SDK_PATHの必須チェック

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

```
MSBuild (dotnet build/publish)
    │
    ├─ WasmBuild.targets（WebAssembly共通）
    │      │
    │      ├─ _WasmResolveReferences
    │      ├─ _WasmBeforeAotCompile
    │      ├─ _WasmAotCompile（AOT時）
    │      │      └─ MonoAOTCompiler（外部タスク）
    │      ├─ _WasmBuildNative（ネイティブビルド時）
    │      │      └─ WASI SDK (clang, wasm-ld)
    │      └─ _WasmGenerateAppBundle
    │
    └─ 出力: {AssemblyName}.wasm / AppBundle/

実行時:
    dotnet run
        │
        └─ wasmtime {AssemblyName}.wasm [--wasi http]
               │
               ├─ WasiEventLoop.PollWasiEventLoopUntilResolved()
               │      │
               │      ├─ ThreadPoolWorkQueue.Dispatch()
               │      └─ PollInterop.Poll()（WASI APIコール）
               │
               └─ WasiHttpHandler.SendAsync()（HTTP通信時）
                      │
                      ├─ WasiHttpInterop.ConvertRequestHeaders()
                      ├─ OutgoingHandlerInterop.Handle()
                      └─ WasiInputStream/WasiOutputStream
```

### データフロー図

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

.NETアセンブリ (.dll)  ─────────────┐
                                    │
runtimeconfig.json ─────────────────┼─▶ MSBuild WasmTargets ──────────▶ {AssemblyName}.wasm
                                    │          │
WASI SDK ───────────────────────────┤          ├─▶ dotnet.wasm
                                    │          │
Mono AOT Compiler ──────────────────┘          └─▶ AppBundle/

実行時データフロー:

[HttpRequestMessage]                [WasiHttpHandler]               [WASI Host]

request.RequestUri ────────────────▶ OutgoingRequest ──────────────▶ wasi:http/outgoing
request.Headers ───────────────────▶ WasiHttpInterop.Convert() ────▶ wasi:http/types
request.Content ───────────────────▶ WasiOutputStream ─────────────▶ wasi:io/streams

[HttpResponseMessage]               [WasiHttpHandler]               [WASI Host]

response.StatusCode ◀──────────────── IncomingResponse ◀─────────── wasi:http/incoming
response.Headers ◀─────────────────── WasiHttpInterop.Convert() ◀── wasi:http/types
response.Content ◀─────────────────── WasiInputStream ◀──────────── wasi:io/streams
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| WasiEventLoop.cs | `src/libraries/System.Private.CoreLib/src/System/Threading/Wasi/WasiEventLoop.cs` | ソース | WASI非同期イベントループの実装 |
| WasiPoll.cs | `src/libraries/System.Private.CoreLib/src/System/Threading/Wasi/WasiPoll.cs` | ソース | WASIポーリングのラッパー |
| WasiHttpHandler.cs | `src/libraries/System.Net.Http/src/System/Net/Http/WasiHttpHandler/WasiHttpHandler.cs` | ソース | WASI HTTP通信ハンドラ |
| WasiHttpInterop.cs | `src/libraries/System.Net.Http/src/System/Net/Http/WasiHttpHandler/WasiHttpInterop.cs` | ソース | WASI HTTPインターオペ |
| WasiInputStream.cs | `src/libraries/System.Net.Http/src/System/Net/Http/WasiHttpHandler/WasiInputStream.cs` | ソース | WASI入力ストリーム |
| WasiOutputStream.cs | `src/libraries/System.Net.Http/src/System/Net/Http/WasiHttpHandler/WasiOutputStream.cs` | ソース | WASI出力ストリーム |
| WorkloadManifest.json.in | `src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.json.in` | テンプレート | ワークロードマニフェスト定義 |
| wasi-console.0.csproj | `src/mono/wasm/templates/templates/wasi-console/wasi-console.0.csproj` | テンプレート | WASIコンソールプロジェクトテンプレート |
| Wasi.Console.Sample.csproj | `src/mono/sample/wasi/console/Wasi.Console.Sample.csproj` | プロジェクト | コンソールサンプル |
| Wasip2.Http.Console.Sample.csproj | `src/mono/sample/wasi/http-p2/Wasip2.Http.Console.Sample.csproj` | プロジェクト | HTTP対応サンプル |
| Wasip2.Sockets.Console.Sample.csproj | `src/mono/sample/wasi/sockets-p2/Wasip2.Sockets.Console.Sample.csproj` | プロジェクト | ソケット対応サンプル |
| BuildTestBase.cs | `src/mono/wasi/Wasi.Build.Tests/BuildTestBase.cs` | テスト | ビルドテスト基盤 |
| WasiTemplateTests.cs | `src/mono/wasi/Wasi.Build.Tests/WasiTemplateTests.cs` | テスト | テンプレートテスト |
| HttpTests.cs | `src/mono/wasi/Wasi.Build.Tests/HttpTests.cs` | テスト | HTTP機能テスト |
| Interop.SocketEvent.cs | `src/libraries/Common/src/Interop/Wasi/System.Native/Interop.SocketEvent.cs` | ソース | WASIソケットイベントInterop |
