ホスト関数

WASMモジュールはホスト関数インポートを通じてランタイム機能にアクセスします。各インポートはimportsリストでエントリごとに明示的に宣言されます。

インポートタイプ

インポート 名前空間 モジュール種別 説明
wasi:cli wasi:cli/* component 環境変数、終了、stdin/stdout/stderr、ターミナル
wasi:io wasi:io/error、wasi:io/streams component ストリームとエラー処理
wasi:poll wasi:io/poll component 非同期ポーリング/協調的yield
wasi:clocks wasi:clocks/* component ウォールクロックとモノトニッククロック
wasi:filesystem wasi:filesystem/* component マウントされたディレクトリを通じたファイルシステムアクセス
wasi:random wasi:random/* component 暗号学的に安全な乱数および非安全な乱数
wasi:sockets wasi:sockets/* component TCP/UDPネットワーキングとDNS解決
wasi:http wasi:http/* component 送信HTTPクライアントリクエスト
funcs wippy:runtime/funcs@0.1.0 component ゲストからのレジストリ関数呼び出し
wippy:actor wippy:actor/process@0.1.0 component PID ID と制限付き Actor mailbox
wasi1 wasi_snapshot_preview1 core WASI Preview 1互換インポート
socket wippy:runtime/socket@0.1.0 core 整数のみのインポートによる、インスタンス所有の送信TCP

8つのwasi:*プロファイル、funcs、wippy:actorはcomponent専用です。coreモジュールでこれらを宣言するとエントリは失敗します。wasi1とsocketはcoreインポートを公開します。

各プロファイルは、短縮名、そのプロファイルが提供する任意のインターフェース名前空間、およびバージョン付き名前空間のいずれでも解決されます。ルックアップ前にバージョンサフィックスは取り除かれるため、wasi:io/poll、wasi:io/poll@0.2.3、wasi:pollはすべて同じプロファイルを選択します。

どのプロファイルにも解決されないインポートは、unsupported wasm host import: <id>でエントリを失敗させます。coreモジュールでcomponent専用プロファイルを指定した場合はwasm host import requires component module: <id>で失敗します。

エントリ設定でインポートを有効にします:

  - name: my_function
    kind: function.wasm
    fs: myns:assets
    path: /module.wasm
    hash: sha256:...
    method: run
    imports:
      - wasi:cli
      - wasi:io
      - wasi:clocks
      - wasi:filesystem
    pool:
      type: inline

モジュールが実際に必要とするインポートのみを宣言してください。

WASIインポート

各wasi:*インポートは関連するWASI Preview 2インターフェースのグループを有効にします。

wasi:clocks

インターフェース: wasi:clocks/wall-clock、wasi:clocks/monotonic-clock

時間操作用のウォールクロックとモノトニッククロック。モノトニッククロックは非同期スリープのためにWippyディスパッチャと統合されています。

wasi:io

インターフェース: wasi:io/error、wasi:io/streams

ストリームの読み書き操作とエラー処理。wasi:io/pollインターフェースはwasi:pollインポートが別途提供します。

wasi:poll

インターフェース: wasi:io/poll

非同期ポーリング。pollインターフェースはディスパッチャを通じた協調的yieldを可能にします。

wasi:cli

インターフェース: wasi:cli/environment、wasi:cli/exit、wasi:cli/stdin、wasi:cli/stdout、wasi:cli/stderr、wasi:cli/terminal-stdin、wasi:cli/terminal-stdout、wasi:cli/terminal-stderr

環境変数、プロセス終了コード、標準I/Oストリームへのアクセス。環境変数はWASI設定を通じてWippy環境レジストリからマッピングされます。

wasi:filesystem

インターフェース: wasi:filesystem/types、wasi:filesystem/preopens

マウントされたディレクトリを通じたファイルシステムアクセス。マウントはエントリごとに設定され、Wippyファイルシステムエントリをゲストパスにマッピングします。

wasi:
  mounts:
    - fs: myns:data
      guest: /data
      read_only: true

wasi:random

インターフェース: wasi:random/random、wasi:random/insecure、wasi:random/insecure-seed

暗号学的に安全な乱数および非安全な乱数生成。

wasi:sockets

インターフェース: wasi:sockets/instance-network、wasi:sockets/ip-name-lookup、wasi:sockets/tcp、wasi:sockets/tcp-create-socket、wasi:sockets/udp、wasi:sockets/udp-create-socket

DNS解決を伴うTCPおよびUDPネットワーキング。ソケット操作はゲストをサスペンドしてディスパッチャ経由で実行され、ディスパッチャはすべてのdial、bind、ルックアップをネットワークサービス上で行います。

wasi:http

インターフェース: wasi:http/types、wasi:http/outgoing-handler

WASMモジュール内からの送信HTTPクライアントリクエスト。WASI HTTP仕様で定義されたリクエスト/レスポンス型をサポートします。

funcs

名前空間: wippy:runtime/funcs@0.1.0

componentゲストからレジストリ関数を呼び出します。2つのエントリポイントが公開されます:

interface funcs {
  call-string: func(target: string, input: string) -> result<string, string>;
  call-bytes: func(target: string, input: list<u8>) -> result<list<u8>, string>;
}

targetはnamespace:name形式のレジストリIDです。すべての呼び出しは、その対象に対するfuncs.callとしてポリシー検査されます。したがってゲストは、呼び出し元のスコープが既に許可している関数にしか到達できません。

wasi1

名前空間: wasi_snapshot_preview1

coreモジュールがWASI Preview 1にリンクすることを宣言します。このプロファイルはpreview1とwasi-preview1でも解決されます。独自のホストは登録せず、Preview 1のインポートは基盤となるWASMランタイムが満たします。

socket

名前空間: wippy:runtime/socket@0.1.0

core(非component)モジュール向けの送信TCPです。ホストは整数のみを扱う4つの関数をエクスポートするため、ゲストはcomponentのツールチェーンなしで利用できます:

関数 シグネチャ 結果
connect (host_ptr: i32, host_len: i32, port: i32, timeout_ms: i32) -> i64 status << 32 | handle
send (handle: i32, buf_ptr: i32, buf_len: i32) -> i64 status << 32 | written
recv (handle: i32, out_ptr: i32, out_cap: i32) -> i64 status << 32 | read
close (handle: i32) -> i32 status

64ビットの結果の上位32ビットがステータスを、下位32ビットが値を保持します。

ステータス 値 意味
OK 0 操作が成功した
Invalid 1 引数が不正、またはメモリ領域が範囲外
Denied 2 ネットワークサービスがdialを拒否した
Failed 3 操作が失敗した
UnknownHandle 4 ハンドルがこのインスタンスの開いている接続ではない
Limit 5 max_open_socketsに到達した
Timeout 6 dialまたは読み書きのデッドラインが切れた

connectはゲストメモリからホスト名を読み取ります。host_lenは1〜253バイト、portは1〜65535である必要があります。timeout_msはdialのデッドラインを狭めます。実効デッドラインはtimeout_msとエントリのsocket_timeout_msのうち小さいほうです。sendとrecvはsocket_timeout_msで制限されます。recvはストリームの正常な終端を、読み取り数0のOKとして報告します。

接続はそれを開いたインスタンスが所有します。ハンドルは別のインスタンスにとっては無意味であり、開いているソケット数はインスタンスごとに数えられ、インスタンスがクローズされるかウォームワーカーがリサイクルされる際にすべての接続が閉じられます。

ネットワークの認可

どちらのソケットホストもアクセス可否を自ら決定しません。すべてのdial、bind、ルックアップはランタイムのネットワークサービスを経由し、そこでsocket.connect、socket.listen、socket.resolveの権限が検査され、プライベートIPポリシーが適用され、選択されている場合はオーバーレイネットワークを通じてルーティングされます。wasi:socketsはさらに、DNSルックアップの前にsocket.resolveを、UDPバインドの前にsocket.listenを事前検査します。

関連項目